page%swap@Sun.COM (Bob Page) (11/13/89)
Submitted-by: dg3i+@andrew.cmu.edu (David Gay) Posting-number: Volume 89, Issue 205 Archive-name: applications/graph.2 # This is a shell archive. # Remove anything above and including the cut line. # Then run the rest of the file through 'sh'. # Unpacked files will be owned by you and have default permissions. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: SHell ARchive # Run the following text through 'sh' to create: # file.h # function.c # function.h # gadgets.c # gadgets.h # This is archive 2 of a 7-part kit. # This archive created: Sun Nov 12 18:23:29 1989 echo "extracting file.h" sed 's/^X//' << \SHAR_EOF > file.h X/* X * GRAPH, Version 1.00 - 4 August 1989 X * X * Copyright 1989, David Gay. All Rights Reserved. X * This software is freely redistrubatable. X */ X X/* Tags for use in files */ X#ifndef FILE_H X#define FILE_H X X#define FILE_TAG 114 /* Variable file */ X#define FILE_END 115 X#define VAR_TAG 116 /* Each variable */ X#define VAR_END 117 X#define GRAPH_TAG 100 /* Tag to recognise graphs in files */ X#define GRAPH_END 101 /* End of graph */ X#define LABEL_TAG 102 /* Labels */ X#define LABEL_END 103 X#define FUNCTION_TAG 104 /* Functions */ X#define FUNCTION_END 105 X#define F_OF_X_TAG 106 /* In each function, you have one of the following */ X#define F_OF_X_END 107 X#define X_Y_TAG 108 X#define X_Y_END 109 X#define R_OF_T_TAG 110 X#define R_OF_T_END 111 X#define R_T_TAG 112 X#define R_T_END 113 X X/* Read/Write raw object from file */ X#define WRITE(file, what) fwrite((char *)&(what), sizeof(what), 1, (file)) X#define READ(file, what) fread((char *)&(what), sizeof(what), 1, (file)) X X#endif SHAR_EOF echo "extracting function.c" sed 's/^X//' << \SHAR_EOF > function.c X/* X * GRAPH, Version 1.00 - 4 August 1989 X * X * Copyright 1989, David Gay. All Rights Reserved. X * This software is freely redistrubatable. X */ X X/* The default/non virtual methods for class function */ X#include <exec/types.h> X#include <intuition/intuition.h> X#include <graphics/text.h> X#include <math.h> X#include <string.h> X X#include "object.h" X#include "object/default.h" X#include "object/function.h" X#include "file.h" X#include "graph.h" X#include "uio.h" X#include "coords.h" X#include "list.h" X#include "grph.h" X#include "user/eval.h" X#include "user/gadgets.h" X#include "tracker.h" X X#include <proto/exec.h> X#include <proto/intuition.h> X#include <proto/graphics.h> X X/* Draw a function */ Xvoid display_function(struct function *this) X{ X int up; X point *pt; X struct RWindow *const rwin = this->o.g->io.rw; X int pen = this->selected ? (this->colour == 3 ? 2 : 3) : this->colour; X X up = TRUE; X X SetAPen(rwin->rp, pen); X SetDrMd(rwin->rp, JAM1); X X /* Scan points (note that all types of function points have point as base c Xlass) */ X for (pt = first(&this->pts); succ(pt); pt = succ(pt)) X { X if (pt->state & EXISTS) X { X if (up) RMove(rwin, pt->x, pt->y); X else RDraw(rwin, pt->x, pt->y); X up = this->showdisc && (pt->state & DISC); X } X else X up = TRUE; X } X} X X/* Select function, redraw in new colour */ Xstatic void select_function(struct function *this) X{ X this->selected = TRUE; X if (this->o.ok && this->o.g->ok && this->o.g->io.rw && this->calc) X display_function(this); X} X X/* Deselect function */ Xstatic struct Region *deselect_function(struct function *this) X{ X this->selected = FALSE; X if (this->o.ok && this->o.g->ok && this->o.g->io.rw && this->calc) X display_function(this); X return NULL; /* No refresh needed */ X} X X/* Did user press mouse on function ? */ Xstatic int down_function(struct function *this) X{ X int inside = FALSE; X X if (this->o.ok && this->calc) X { X struct graph *g = this->o.g; X point *pt; X long sx = ftol(g->io.rw->sx(g->io.rw, g->s.x)); X long sy = ftol(g->io.rw->sy(g->io.rw, g->s.y)); X long x0, y0, x1, y1; X int up = TRUE; X X /* Check if mouse "near" drawn line */ X for (pt = first(&this->pts); succ(pt); pt = succ(pt)) X { X if (pt->state & EXISTS) X { X x1 = ftol(g->io.rw->sx(g->io.rw, pt->x)); X y1 = ftol(g->io.rw->sy(g->io.rw, pt->y)); X X if (!up) /* segment exists, calc distance to it */ X { X /* A little vectorial algebra */ X long ab_x, ab_y, u_x, u_y, h, hd, dist_x, dist_y, dist; X X ab_x = sx - x0; ab_y = sy - y0; X u_x = x1 - x0; u_y = y1 - y0; X h = (ab_x * u_x + ab_y * u_y); X hd = (u_x * u_x + u_y * u_y); X if (hd != 0 && 0 <= h && h <= hd) /* intersection on segmen Xt */ X { X dist_x = (hd * ab_x - h * u_x) / hd; dist_y = (hd * ab_ Xy - h * u_y) / hd; X dist = dist_x * dist_x + dist_y * dist_y; X if (dist < (FDIST * FDIST)) X { X /* We're near segment ! */ X inside = TRUE; X break; X } X } X /* Near point ? */ X else if ((x1 - sx) * (x1 - sx) + (y1 - sy) * (y1 - sy) <= F XDIST * FDIST) X { X inside = TRUE; X break; X } X } X X up = this->showdisc && (pt->state & DISC); X x0 = x1; y0 = y1; X } X else X up = TRUE; X X } X } X return inside; X} X X/* Impossible ... */ Xstatic void move_function(struct function *this) X{ X} X X/* Nothing to do */ Xstatic struct Region *up_function(struct function *this) X{ X return NULL; X} X X/* redraw function, calc if necessary */ Xstatic void draw_function(struct function *this, int allow_mes) X{ X if (!this->calc) this->calc = this->calcf(this, allow_mes); X if (this->calc) display_function(this); X} X X/* variable name changed. recalc necessary ? */ Xstatic void var_change_function(struct function *this, char *name) X{ X if (this->calc && FindName(&this->used, name)) X { X free_list(&this->pts, this->sizept); X this->calc = FALSE; X } X} X X/* Write function to file */ Xstatic int save_function(struct function *this, FILE *f) X{ X short tag = FUNCTION_TAG; X short end = FUNCTION_END; X short showdisc = this->showdisc; /* Can't write bitfields directly ... */ X short nicedisc = this->nicedisc; X X return WRITE(f, tag) && X this->save(this, f) && /* Easier than rewriting this for each fun Xction */ X WRITE(f, this->o.name) && X WRITE(f, this->vname) && X WRITE(f, this->min) && X WRITE(f, this->max) && X WRITE(f, this->steps) && X WRITE(f, this->colour) && X WRITE(f, showdisc) && X WRITE(f, nicedisc) && X WRITE(f, end); X} X X/* Read a function from a file */ Xstruct function *load_function(struct graph *g, FILE *f) X{ X short tag; X struct function *this; X X if (READ(f, tag)) /* Determine which type of function */ X switch (tag) X { X case F_OF_X_TAG: X this = (struct function *)load_f_of_x(g, f); X break; X case X_Y_TAG: X this = (struct function *)load_x_y(g, f); X break; X case R_OF_T_TAG: X this = (struct function *)load_r_of_t(g, f); X break; X case R_T_TAG: X this = (struct function *)load_r_t(g, f); X break; X default: X message(g, "Not a graph file", (char *)NULL); X } X return this; X} X X/* Read "standard" part of function from file */ Xint load_rest(struct function *this, FILE *f) X{ X short showdisc, nicedisc, end; X X if (READ(f, this->o.name) && X READ(f, this->vname) && X READ(f, this->min) && X READ(f, this->max) && X READ(f, this->steps) && X READ(f, this->colour) && X READ(f, showdisc) && /* Can't read bitfields directly */ X READ(f, nicedisc) && X READ(f, end) && X end == FUNCTION_END) X { X this->showdisc = showdisc; X this->nicedisc = nicedisc; X return TRUE; X } X return FALSE; X} X X/* Nothing to do (don't care about resolution) */ Xstatic int inform_function(struct function *this) X{ X return TRUE; X} X X/* idem */ Xstatic void confirm_function(struct object *this, int ok) X{ X} X X/* Standard function init */ Xvoid init_function(struct function *this, struct graph *g, char *name) X{ X const static struct function def_f = X { X { X { NULL }, NULL, "", FALSE, 0, 0, X /* Default methods */ X (void *)uncalled, (void *)select_function, (void *)deselect_functio Xn, X (void *)down_function, (void *)move_function, (void *)up_function, X (void *)uncalled, (void *)draw_function, (void *)ref_uncalled, X (void *)uncalled, (void *)var_change_function, (void *)save_functio Xn, X (void *)inform_function, (void *)confirm_function X }, X (void *)uncalled, (void *)uncalled, X "", NOVAL, NOVAL, INOVAL, X 1, TRUE, TRUE, FALSE, FALSE X }; X X *this = def_f; X this->o.g = g; X strcpy(this->o.name, name); X init_var_list(&this->used); X} X X/* Create a new function (ask user which type he wants) */ Xstruct function *new_function(struct graph *g) X{ X struct Requester *req; X struct Memory *m; X struct Gadget *gl = NULL, *fx, *xy, *rt, *r2; X char name[FNAMELEN]; X int ret = FALSE; X struct function *o = NULL; X X name[0] = '\0'; X X if ((m = NewMemory()) && X (req = InitReq(50, 20, 230, 105, m)) && X SetReqBorder(req, 1, m) && X AddIntuiText(&req->ReqText, "Add Function", 67, 6, m) && X AddText(&gl, 0, "Name ", FALSE, name, FNAMELEN, TRUE, 0, RELVERIFY, 51, X 20, 100, 10, TRUE, m) && X (fx = AddRadio(&gl, 0, "f(x)", TRUE, SELECTED, RELVERIFY, 28, 11, 40, 1 X0, 10, m)) && X (rt = AddRadio(&gl, 0, "r(theta)", TRUE, 0, RELVERIFY, 26, 105, 40, 10, X 10, m)) && X (xy = AddRadio(&gl, 0, "x(t),y(t)", TRUE, 0, RELVERIFY, 22, 11, 60, 10, X 10, m)) && X (r2 = AddRadio(&gl, 0, "r(t),theta(t)", TRUE, 0, RELVERIFY, 14, 105, 60 X, 10, 10, m)) && X AddBox(&gl, TRUE, "Ok", 0, RELVERIFY | ENDGADGET, 25, 80, 65, 15, FALSE X, m) && X AddBox(&gl, FALSE, "Cancel", 0, RELVERIFY | ENDGADGET, 140, 80, 65, 15, X FALSE, m)) X { X SetReqGadgets(req, gl); X if (ret = DoRequest(req, g, std_ghandler)) X { X strip(name); X if (*name) X { X if (fx->Flags & SELECTED) o = (struct function *)new_f_of_x(g, Xname); X else if (xy->Flags & SELECTED) o = (struct function *)new_x_y(g X, name); X else if (rt->Flags & SELECTED) o = (struct function *)new_r_of_ Xt(g, name); X else o = (struct function *)new_r_t(g, name); X } X else X message(g, "Blank names not allowed", (char *)NULL); X } X } X Free(m); X return o; X} X SHAR_EOF echo "extracting function.h" sed 's/^X//' << \SHAR_EOF > function.h X/* X * GRAPH, Version 1.00 - 4 August 1989 X * X * Copyright 1989, David Gay. All Rights Reserved. X * This software is freely redistrubatable. X */ X X/* class function, inherits from class object. The actual function types are su Xb-classes of this one */ X#ifndef FUNCTION_H X#define FUNCTION_H X X#include "list.h" X#include "object.h" X#include "graph.h" X#include "user/eval.h" X#include <stddef.h> X X#define MAXERROR 0.2 /* For discontinuities */ X#define MAXITER 4 /* In improvement algo */ X#define FLAT 2 /* number of pixels allowed in "flat" discontinuities */ X#define DEFSTEPS 100 /* Default number of steps */ X#define FDIST 5 /* Max (y) distance for function select */ X X/* class function (inherited from class object). Fields are public. */ Xstruct function { X struct object o; X int (*calcf)(struct function *this, int allow_mes); /* Recalculate values o Xf points */ X int (*save)(struct function *this, FILE *f); /* Save function specif Xic info. to file */ X X /* Information global to all types of functions */ X char vname[VARLEN]; /* name of variable */ X double min, max; /* Limits for variable */ X int steps; /* Number of points to calculate */ X BYTE colour; /* Colour in which to draw */ X int showdisc : 1; /* Show discontinuities ? */ X int nicedisc : 1; /* Allow "nice" discontinuities */ X X /* State info */ X int calc : 1; /* Points calculated ? */ X int selected : 1; /* function selected ? */ X variable var; /* Actual variable */ X var_list used; /* Vars this function depends on */ X list pts; /* Points composing this, different structure for each Xtype of function */ X size_t sizept; /* Size of one point (for delete) */ X}; X X/* Flags for point state */ X#define EXISTS 1 /* Function is defined here */ X#define DISC 2 /* This is a discontinuity */ X#define OK 4 /* All is well */ X X/* The base class for a point */ Xstruct point { X node node; X char state; X double x, y; X}; X Xtypedef struct point point; X X/* Create/load the various types of function */ Xstruct f_of_x *new_f_of_x(struct graph *g, char *name); Xstruct x_y *new_x_y(struct graph *g, char *name); Xstruct r_of_t *new_r_of_t(struct graph *g, char *name); Xstruct r_t *new_r_t(struct graph *g, char *name); Xstruct f_of_x *load_f_of_x(struct graph *g, FILE *f); Xstruct x_y *load_x_y(struct graph *g, FILE *f); Xstruct r_of_t *load_r_of_t(struct graph *g, FILE *f); Xstruct r_t *load_r_t(struct graph *g, FILE *f); X X/* A few useful functions ... */ Xvoid display_function(struct function *this); /* Draws a function */ Xvoid init_function(struct function *this, struct graph *g, char *name); /* Stan Xdard init. */ Xint load_rest(struct function *this, FILE *f); /* Load public part of function X*/ X X#endif X SHAR_EOF echo "extracting gadgets.c" sed 's/^X//' << \SHAR_EOF > gadgets.c X/* Routines to create various types of gadgets, menus, etc X Could do with a few comments and some documentation ... X This code is placed in the public domain. X David Gay, 1989. X*/ X X#include <proto/exec.h> X#include <exec/nodes.h> X#include <exec/lists.h> X#include <exec/memory.h> X#include <graphics/gfx.h> X#include <intuition/intuition.h> X#include <proto/graphics.h> X#include <proto/intuition.h> X#include <proto/diskfont.h> X#include "user/gadgets.h" X#include <string.h> X X#define XDOUBLEMARGIN 4 /* Margin for "double" border reque Xsters */ X#define YDOUBLEMARGIN 4 X#define GADGTEXTX 4 /* How far away (X) text is from Op Xtion/Radio gadgets */ X#define GADGTEXTY 4 /* idem, but when text above gadget X */ X#define TEXTBORDERX 2 /* How far out text gadget rectangl Xe is */ X#define TEXTBORDERY 4 X#define MENUMARGIN 20 /* Spacing between menus */ X#define TEXTMARGIN 10 /* Space around text items */ X#define TEXTGAP 2 /* Space above & below text items * X/ X#define RULEHEIGHT 2 /* Height of rules */ X#define RULEGAP 6 /* Space above & below rules */ X#define RULEMARGIN 10 /* idem, but left & right */ X#define MINITEMWIDTH (RULEMARGIN + 10) /* Min. menu item width */ X#define SUBX 30 /* Sub item position */ X Xboolean CheckFont(struct Memory *); X Xstruct Memory X{ X struct MinList Fonts; X struct MinList Lists; X struct Remember *Mem; X}; X Xstruct FontNode X{ X struct MinNode fn_Node; X struct TextFont *font; X}; X Xstruct ITextNode X{ X struct MinNode it_node; X struct IntuiText it; X}; X Xtypedef struct Gadget GArray[1]; X Xstruct ListInfo X{ X struct MinNode li_node; X char *buf; X long len; X struct List *list; X struct MinList ilist; X struct IntuiText *blank; X long nb, current, pos; X struct Gadget *arrow1, *arrow2, *strg, *sld; X GArray *glist; X long visible, exists, dispchars; X ULONG clicksecs, clickmics; X long clickpos; X}; X Xstatic struct TextAttr topaz8 = { "topaz.font", 8 }; Xstatic BYTE fore = 1, back = 0, mode = JAM1, depth = 2; Xstatic struct TextAttr *ta = &topaz8; Xstatic boolean fontopen; Xstatic struct TextFont *font; X X Xstatic UWORD chip down_data[] = { X 0xF83E,0xF83E,0xF83E,0xC006,0xE00E,0xF01E,0xF83E,0xFC7E, X 0xFEFE,0xFFFE,0x07C0,0x07C0,0x07C0,0x3FF8,0x1FF0,0x0FE0, X 0x07C0,0x0380,0x0100,0x0000 X}; X Xstatic struct Image down_img = { X 0, 1, X 15, 10, X 2, X down_data, X 0x0003, 0x0000, X NULL X}; X Xstatic UWORD chip up_data[] = { X 0xFEFE,0xFC7E,0xF83E,0xF01E,0xE00E,0xC006,0xF83E,0xF83E, X 0xF83E,0xFFFE,0x0100,0x0380,0x07C0,0x0FE0,0x1FF0,0x3FF8, X 0x07C0,0x07C0,0x07C0,0x0000 X}; X Xstatic struct Image up_img = { X 0, 1, X 15, 10, X 2, X up_data, X 0x0003, 0x0000, X NULL X}; X X/* Returns number of nodes, or -1 for failure */ Xstatic long build_ilist(struct ListInfo *li) X{ X int cnt = 0; X struct Node *scan; X X NewList((struct List *)&li->ilist); X X for (scan = li->list->lh_Head; scan->ln_Succ; scan = scan->ln_Succ, cnt++) X { X struct ITextNode *in = AllocMem(sizeof(struct ITextNode) + li->dispchar Xs + 1, MEMF_CLEAR); X char *str; X struct IntuiText *it; X int j; X X if (!in) return -1; X it = (struct IntuiText *)&in->it; X str = (char *)(in + 1); X X str[li->dispchars] = '\0'; X X strncpy(str, scan->ln_Name, li->dispchars); X for (j = strlen(str); j < li->dispchars; j++) str[j] = ' '; X X it->FrontPen = fore; it->BackPen = back; X it->DrawMode = JAM2; X it->ITextFont = ta; X it->IText = str; X X AddTail((struct List *)&li->ilist, (struct Node *)in); X } X li->exists = li->visible > cnt ? cnt : li->visible; X return cnt; X} X Xstatic void free_ilist(struct ListInfo *li) X{ X struct MinNode *scan, *next; X X for (scan = li->ilist.mlh_Head; next = scan->mln_Succ; scan = next) X FreeMem(scan, sizeof(struct ITextNode) + li->dispchars + 1); X} X Xstatic void recalc_glist(struct ListInfo *li) X{ X int i; X struct ITextNode *scan; X X for (i = 0, scan = (struct ITextNode *)li->ilist.mlh_Head; i < li->pos; i++ X, scan = (struct ITextNode *)scan->it_node.mln_Succ) X ; X for (i = 0; i < li->exists; i++, scan = (struct ITextNode *)scan->it_node.m Xln_Succ) X (*li->glist)[i].GadgetText = &scan->it; X for (; i < li->visible; i++) X (*li->glist)[i].GadgetText = li->blank; X X if (li->current >= li->pos && li->current < li->pos + li->exists) X (*li->glist)[li->current - li->pos].Flags |= SELECTED; X} X Xstruct Memory *NewMemory() X{ X struct Memory *mem; X struct Remember *key = NULL; X X mem = (struct Memory *)AllocRemember(&key, sizeof(struct Memory), MEMF_CLEA XR); X if (mem) X { X mem->Mem = key; X NewList((struct List *)&mem->Fonts); X NewList((struct List *)&mem->Lists); X } X X return(mem); X} X Xvoid Free(mem) Xstruct Memory *mem; X{ X struct MinNode *mn; X X if (mem) X { X for (mn = mem->Fonts.mlh_Head; mn->mln_Succ; mn = mn->mln_Succ) X CloseFont(((struct FontNode *)mn)->font); X for (mn = mem->Lists.mlh_Head; mn->mln_Succ; mn = mn->mln_Succ) X free_ilist((struct ListInfo *)mn); X X FreeRemember(&mem->Mem, TRUE); X } X} X Xvoid ModSys(f, b, m, font) Xlong f, b, m; Xstruct TextAttr *font; X{ X if (f != -1) fore = f; X if (b != -1) back = b; X if (m != -1) mode = m; X if (font) X { X ta = font; X fontopen = FALSE; X } X} X Xvoid SetDepth(d) Xlong d; X{ X depth = d; X} X Xstruct Requester *InitReq(left, top, width, height, mem) Xlong left, top, width, height; Xstruct Memory *mem; X{ X struct Requester *req; X X req = (struct Requester *)AllocRemember(&mem->Mem, sizeof(struct Requester) X, MEMF_CLEAR); X if (req) X { X req->LeftEdge = left; req->TopEdge = top; X req->Width = width; req->Height = height; X req->BackFill = back; X } X X return(req); X} X Xboolean SetReqBorder(req, type, mem) Xstruct Requester *req; XLONG type; Xstruct Memory *mem; X{ X struct Border *b = NULL; X X switch (type) X { X case 1: X if (!AddRectBorder(&b, XDOUBLEMARGIN / 2, YDOUBLEMARGIN / 2, req->W Xidth - XDOUBLEMARGIN, req->Height - YDOUBLEMARGIN, mem)) X break; X case 0: X if (!AddRectBorder(&b, 0, 0, req->Width, req->Height, mem)) X b = NULL; X break; X default: X b = (struct Border *)type; X break; X } X X return((req->ReqBorder = b) != NULL); X} X Xvoid SetReqGadgets(req, gl) Xstruct Requester *req; Xstruct Gadget *gl; X{ X struct Gadget *g; X X for (g = gl; g; g = g->NextGadget) X g->GadgetType |= REQGADGET; X X req->ReqGadget = gl; X} X Xvoid SetReqText(req, it) Xstruct Requester *req; Xstruct IntuiText *it; X{ X req->ReqText = it; X} X Xstruct Gadget *AddBox(gl, id, text, flags, act, x, y, w, h, thick, mem) Xstruct Gadget **gl; Xchar *text; Xlong id, flags, act, x, y, w, h, thick; Xstruct Memory *mem; X{ X BYTE *data; X struct Gadget *gadg = NULL; X int i, tl, tx, ty, len = strlen(text); X struct RastPort rp, rp2; X struct BitMap bm, bm2; X struct Image *im, *im2; X X if (CheckFont(mem) && X (gadg = (struct Gadget *)AllocRemember(&mem->Mem, sizeof(struct Gadget) X + 2 * sizeof(struct Image), MEMF_CLEAR)) && X (data = (BYTE *)AllocRemember(&mem->Mem, 2 * depth * RASSIZE(w, h), MEM XF_CLEAR | MEMF_CHIP))) X { X im2 = (im = (struct Image *)(gadg + 1)) + 1; X X InitBitMap(&bm, depth, w, h); X InitBitMap(&bm2, depth, w, h); X for (i = 0; i < depth; i++) X { X bm.Planes[i] = data; X bm2.Planes[i] = data + RASSIZE(w, h) * depth; X data += RASSIZE(w, h); X } X InitRastPort(&rp); X rp.BitMap = &bm; X InitRastPort(&rp2); X rp2.BitMap = &bm2; X SetAPen(&rp, fore); X SetAPen(&rp2, fore); X X im->Width = im2->Width = w; X im->Height = im2->Height = h; X im->Depth = im2->Depth = depth; X im->ImageData = (USHORT *)bm.Planes[0]; X im2->ImageData = (USHORT *)bm2.Planes[0]; X im->PlanePick = im2->PlanePick = 0xff; X X SetRast(&rp, back); X SetRast(&rp2, back); X DrawRoundedRect(&rp, 0, 0, w, h); X FillRoundedRect(&rp2, 0, 0, w, h); X if (thick) X { X DrawRoundedRect(&rp, 1, 1, w - 2, h - 2); X DrawRoundedRect(&rp, 1, 0, w - 2, h); X } X X SetFont(&rp, font); X SetFont(&rp2, font); X tl = TextLength(&rp, text, len); X tx = (w - tl) / 2; X ty = (h - font->tf_YSize + 1) / 2 + font->tf_Baseline; X SetDrMd(&rp, JAM1); X Move(&rp, tx, ty); Text(&rp, text, len); X SetAPen(&rp2, back); SetDrMd(&rp2, JAM1); X Move(&rp2, tx, ty); Text(&rp2, text, len); X X gadg->LeftEdge = x; X gadg->TopEdge = y; X gadg->Width = w; X gadg->Height = h; X gadg->GadgetType = BOOLGADGET; X X gadg->GadgetRender = (APTR)im; X gadg->SelectRender = (APTR)im2; X gadg->GadgetID = id; X gadg->Flags = GADGHIMAGE | GADGIMAGE | flags; X gadg->Activation = act; X X AppendGadget(gl, gadg); X } X X return(gadg); X} X Xstruct Gadget *AddRadio(gl, id, text, side, flags, act, mutex, x, y, w, h, mem) X Xstruct Gadget **gl; Xchar *text; Xlong id, side, flags, act, x, y, w, h, mutex; Xstruct Memory *mem; X{ X BYTE *data; X struct Gadget *gadg = NULL; X struct IntuiText *it = NULL; X struct RastPort rp, rp2; X struct BitMap bm, bm2; X struct Image *im, *im2; X int tl, bx, i; X struct AreaInfo areainf; X struct TmpRas tmpras; X BYTE areabuf[4 * 5]; X PLANEPTR plane; X X if (AddIntuiText(&it, text, side ? w + GADGTEXTX : 0, 0, mem) && X (gadg = (struct Gadget *)AllocRemember(&mem->Mem, sizeof(struct Gadget) X + 2 * sizeof(struct Image), MEMF_CLEAR)) && X (data = (BYTE *)AllocRemember(&mem->Mem, 2 * depth * RASSIZE(w, h), MEM XF_CLEAR | MEMF_CHIP))) X { X tl = IntuiTextLength(it); X it->TopEdge = (h - font->tf_YSize) / 2; X X gadg->LeftEdge = side ? x : x - tl - GADGTEXTX; X gadg->TopEdge = y; X gadg->Width = tl + GADGTEXTX + w; X gadg->Height = h; X gadg->GadgetType = BOOLGADGET; X gadg->MutualExclude = mutex; X X bx = side ? 0 : tl + GADGTEXTX; X X im2 = (im = (struct Image *)(gadg + 1)) + 1; X X InitBitMap(&bm, depth, w, h); X InitBitMap(&bm2, depth, w, h); X for (i = 0; i < depth; i++) X { X bm.Planes[i] = data; X bm2.Planes[i] = data + RASSIZE(w, h) * depth; X data += RASSIZE(w, h); X } X InitRastPort(&rp); X rp.BitMap = &bm; X InitRastPort(&rp2); X rp2.BitMap = &bm2; X if (plane = (PLANEPTR)AllocRaster(w, h)) X { X InitTmpRas(&tmpras, plane, RASSIZE(w, h)); X rp2.TmpRas = &tmpras; X memset(areabuf, 0, sizeof(areabuf)); X InitArea(&areainf, (short *)areabuf, 4); X rp2.AreaInfo = &areainf; X X SetAPen(&rp, fore); X SetAPen(&rp2, fore); X X im->Width = im2->Width = w; X im->Height = im2->Height = h; X im->LeftEdge = im2->LeftEdge = bx; X im->Depth = im2->Depth = depth; X im->ImageData = (USHORT *)bm.Planes[0]; X im2->ImageData = (USHORT *)bm2.Planes[0]; X im->PlanePick = im2->PlanePick = 0xff; X X SetRast(&rp, back); X SetRast(&rp2, back); X DrawEllipse(&rp, w/2, h/2, w/2 - 1, h/2 - 1); X DrawEllipse(&rp2, w/2, h/2, w/2 - 1, h/2 - 1); X AreaEllipse(&rp2, w/2, h/2, w/4, h/4); X AreaEnd(&rp2); X FreeRaster(plane, w, h); X rp2.TmpRas = NULL; X rp2.AreaInfo = NULL; X X gadg->GadgetRender = (APTR)im; X gadg->SelectRender = (APTR)im2; X gadg->GadgetText = it; X gadg->GadgetID = id; X gadg->Flags = GADGHIMAGE | GADGIMAGE | flags; X gadg->Activation = act; X X AppendGadget(gl, gadg); X } X else X gadg = NULL; X } X return(gadg); X} X Xstruct Gadget *AddOption(gl, id, text, side, flags, act, x, y, w, h, mem) Xstruct Gadget **gl; Xchar *text; Xlong id, side, flags, act, x, y, w, h; Xstruct Memory *mem; X{ X struct Gadget *gadg = NULL; X struct IntuiText *it = NULL; X struct Border *b = NULL, *b2 = NULL; X int tl, bx, f = fore, ba = back; X X if (AddIntuiText(&it, text, side ? w + GADGTEXTX : 0, 0, mem) && X (gadg = (struct Gadget *)AllocRemember(&mem->Mem, sizeof(struct Gadget) X, MEMF_CLEAR))) X { X gadg->Height = h; X tl = IntuiTextLength(it); X it->TopEdge = (h - font->tf_YSize) / 2; X X gadg->LeftEdge = side ? x : x - tl - GADGTEXTX; X gadg->TopEdge = y; X gadg->Width = tl + 4 + w; X gadg->GadgetType = BOOLGADGET; X X bx = side ? 0 : tl + GADGTEXTX; X if (AddLineBorder(&b, bx, 0, bx + w - 1, h - 1, mem) && X AddLineBorder(&b, bx + w - 1, 0, bx, h - 1, mem) && X AddRectBorder(&b, bx, 0, w, h, mem) && X (fore = ba, back = f, AddLineBorder(&b2, bx, 0, bx + w - 1, h - 1, Xmem)) && X AddLineBorder(&b2, bx + w - 1, 0, bx, h - 1, mem) && X (fore = f, back = ba, AddRectBorder(&b2, bx, 0, w, h, mem))) X { X gadg->GadgetRender = (APTR)b2; X gadg->SelectRender = (APTR)b; X gadg->GadgetText = it; X gadg->GadgetID = id; X gadg->Flags = GADGHIMAGE | flags; X gadg->Activation = TOGGLESELECT | act; X X AppendGadget(gl, gadg); X } X else X gadg = NULL; X } X X fore = f; back = ba; X return(gadg); X} X Xstruct Gadget *AddText(struct Gadget **gl, long id, char *text, long above, cha Xr *buf, long maxlen, long undo, long flags, long act, long x, long y, long w, lo Xng h, long noborder, struct Memory *mem) X{ X BYTE *data; X struct StringInfo *si; X struct Gadget *gadg = NULL; X struct IntuiText *it = NULL; X int tl; X struct Border *b = NULL; X char *undobuf; X X data = (BYTE *)AllocRemember(&mem->Mem, sizeof(struct Gadget) + sizeof(stru Xct StringInfo) + (undo ? maxlen + 1: 0), MEMF_CLEAR); X if (data) X { X gadg = (struct Gadget *)data; X si = (struct StringInfo *)(gadg + 1); X undobuf = undo ? data + sizeof(struct Gadget) + sizeof(struct StringInf Xo) : NULL; X X if (AddIntuiText(&it, text, 0, 0, mem)) X { X tl = IntuiTextLength(it); X if (above) X { X it->TopEdge = -font->tf_YSize - GADGTEXTY; X it->LeftEdge = 0; X } X else X { X it->TopEdge = h - font->tf_YSize - 2; X it->LeftEdge = -tl - GADGTEXTX; X } X X gadg->LeftEdge = x; X gadg->TopEdge = y; X gadg->Width = w; X gadg->Height = h; X gadg->GadgetType = STRGADGET; X X if (noborder || AddRectBorder(&b, -TEXTBORDERX + 1, -TEXTBORDERY + X1, w + TEXTBORDERX, h + TEXTBORDERY, mem)) X { X gadg->GadgetRender = (APTR)b; X gadg->GadgetText = it; X gadg->GadgetID = id; X gadg->Flags = GADGHCOMP | flags; X gadg->Activation = act; X gadg->SpecialInfo = (APTR)si; X X si->Buffer = buf; X si->UndoBuffer = undobuf; X si->MaxChars = maxlen; X X AppendGadget(gl, gadg); X } X else X gadg = NULL; X } X else X gadg = NULL; X } X X return(gadg); X} X Xstruct Gadget *AddSlider(struct Gadget **gl, long id, long act, long x, long y, X long w, long h, long vert, long knobsize, struct Memory *mem) X{ X BYTE *data; X struct Gadget *gg = NULL; X struct PropInfo *info; X struct Image *im; X X data = (BYTE *)AllocRemember(&mem->Mem, sizeof(struct Gadget) + sizeof(stru Xct PropInfo) + sizeof(struct Image), MEMF_CLEAR); X if (data) X { X gg = (struct Gadget *)data; X info = (struct PropInfo *)(data + sizeof(struct Gadget)); X im = (struct Image *)(data + sizeof(struct Gadget) + sizeof(struct Prop XInfo)); X X gg->LeftEdge = x; X gg->TopEdge = y; X gg->Width = w; X gg->Height = h; X gg->Flags = GADGHCOMP | GADGIMAGE | X (y < 0 ? GRELBOTTOM : 0) | X (x < 0 ? GRELRIGHT : 0) | X (w < 0 ? GRELWIDTH : 0) | X (h < 0 ? GRELHEIGHT : 0); X gg->Activation = act; X gg->GadgetType = PROPGADGET; X gg->GadgetRender = (APTR)im; /* dummy image, why ? */ X gg->SpecialInfo = (APTR)info; X gg->GadgetID = id; X X info->Flags = AUTOKNOB | X (vert ? FREEVERT : FREEHORIZ); X if (vert) info->VertBody = knobsize; X else info->HorizBody = knobsize; X X AppendGadget(gl, gg); X } X return(gg); X} X X/* BUG: Arrows don't use selected colours */ Xstruct ListInfo *AddList(struct Gadget **gl, long id, char *text, struct List * Xlist, char *buf, long len, long flags, long act, long x, long y, long w, long h, X long noborder, struct Memory *mem) X{ X long ok = FALSE; X struct ListInfo *li; X int i; X long nb; X int a = font->tf_YSize; X int dispchars = (w - 15 - 3) / font->tf_XSize; X int nblines = (h - 2) / a; X X if (CheckFont(mem) && X (li = (struct ListInfo *)AllocRemember(&mem->Mem, sizeof(struct ListInf Xo) + dispchars + 1, MEMF_CLEAR))) X { X char *spaces = (char *)(li + 1); X X memset(spaces, ' ', dispchars); X spaces[dispchars] = '\0'; X X AddHead((struct List *)&mem->Lists, (struct Node *)li); X if (nblines >= 5 && a * (nblines - 2) - 26 > 20 && w > 15 + 3 + 32) X { X w = font->tf_XSize * dispchars + 15 + 3; X h = a * nblines + 2; X X li->buf = buf; X li->len = len; X li->list = list; X li->pos = 0; X li->current = -1; X li->visible = nblines - 2; X li->dispchars = dispchars; X li->clickpos = -1; X X if ((li->nb = nb = build_ilist(li)) != -1 && X AddIntuiText(&li->blank, spaces, 0, 0, mem)) X { X struct Gadget *arrow1, *arrow2, *sld; X struct Border *b = NULL; X long knobsize; X X if (nb == 0) X knobsize = 0xffff; X else X { X knobsize = 0xffff * li->exists; X knobsize /= nb; X } X X if ((sld = AddSlider(gl, id, RELVERIFY, x + w - 16, y + 13, 15, X h - 2 * a - 26, TRUE, knobsize, mem)) && X (arrow1 = (struct Gadget *)AllocRemember(&mem->Mem, 3 * siz Xeof(struct Gadget), MEMF_CLEAR)) && X AddRectBorder(&b, 0, 0, w, h - 2 * a, mem) && X AddRectBorder(&b, w - 17, 12, 17, h - 2 * a - 24, mem) && X AddLineBorder(&b, w - 17, 0, w - 17, h - 2 * a - 1, mem)) X { X struct Gadget *strg, *cadre; X int tx; X X sld->UserData = (APTR)li; X li->sld = sld; X arrow2 = arrow1 + 1; X arrow1->TopEdge = y + 1; X arrow1->LeftEdge = x + w - 16; X arrow1->Width = 15; X arrow1->Height = 11; X arrow1->Flags = GADGHCOMP | GADGIMAGE; X arrow1->Activation = GADGIMMEDIATE | RELVERIFY; X arrow1->GadgetType = BOOLGADGET; X arrow1->GadgetRender = (APTR)&up_img; X arrow1->UserData = (APTR)li; X arrow1->GadgetID = id; X AppendGadget(gl, arrow1); X X li->arrow1 = arrow1; X arrow2->LeftEdge = x + w - 16; X arrow2->TopEdge = y + h - 2 * a - 1 - 11; X arrow2->Width = 15; X arrow2->Height = 11; X arrow2->Flags = GADGHCOMP | GADGIMAGE; X arrow2->Activation = GADGIMMEDIATE | RELVERIFY; X arrow2->GadgetType = BOOLGADGET; X arrow2->GadgetRender = (APTR)&down_img; X arrow2->UserData = (APTR)li; X arrow2->GadgetID = id; X AppendGadget(gl, arrow2); X li->arrow2 = arrow2; X X cadre = arrow2 + 1; X cadre->LeftEdge = x; X cadre->TopEdge = y; X cadre->Width = 1; X cadre->Height = 1; X cadre->Flags = GADGHNONE; X cadre->GadgetType = BOOLGADGET; X cadre->GadgetRender = (APTR)b; X cadre->UserData = (APTR)li; X cadre->GadgetID = id; X AppendGadget(gl, cadre); X X tx = font->tf_XSize * strlen(text); X if (tx > w - 32) tx = w - 32; X if (strg = AddText(gl, id, text, FALSE, buf, len, TRUE, fla Xgs, act | GADGIMMEDIATE, x + tx + GADGTEXTX, y + h - a - 2, w - tx - GADGTEXTX, Xa + 2, noborder, mem)) X { X GArray *bl; X X strg->UserData = (APTR)li; X li->strg = strg; X X if (bl = (GArray *)AllocRemember(&mem->Mem, li->visible X * sizeof(struct Gadget), MEMF_CLEAR)) X { X li->glist = bl; X for (i = 0; i < li->visible; i++) X { X struct Gadget *gg = &(*bl)[i]; X X gg->LeftEdge = x + 1; X gg->TopEdge = y + i * a + 1; X gg->Width = w - 18; X gg->Height = a; X gg->Flags = GADGHCOMP; X gg->Activation = GADGIMMEDIATE; X gg->GadgetType = BOOLGADGET; X gg->UserData = (APTR)li; X gg->GadgetID = id; X AppendGadget(gl, gg); X } X recalc_glist(li); X ok = TRUE; X } X } X } X } X } X } X return ok ? li : NULL; X} X Xlong ModifyList(struct Gadget *gg, struct Requester *req, struct Window *win, l Xong up) X{ X struct ListInfo *li = (struct ListInfo *)gg->UserData; X int change = FALSE, ret = 0; X X switch (gg->GadgetType & ~GADGETTYPE) X { X case STRGADGET: X if (!up && li->current != -1) X { X change = TRUE; X (*li->glist)[li->current - li->pos].Flags &= ~SELECTED; X li->current = li->clickpos = -1; X } X else if (up) ret = 1; X break; X case PROPGADGET: X { X struct PropInfo *pi = (struct PropInfo *)gg->SpecialInfo; X X if (li->current != -1) (*li->glist)[li->current - li->pos].Flag Xs &= ~SELECTED; X X li->pos = (pi->VertPot + 1) * (li->nb - li->exists) >> 16; X recalc_glist(li); X change = TRUE; X } X break; X case BOOLGADGET: X if (gg == li->arrow1 || gg == li->arrow2) X { X if (up) X { X long newpos; X X if (li->current != -1) (*li->glist)[li->current - li->pos]. XFlags &= ~SELECTED; X newpos = li->pos + (gg == li->arrow1 ? -1 : 1); X if (newpos >= 0 && newpos <= li->nb - li->exists) X { X struct PropInfo *pi = (struct PropInfo *)li->sld->Speci XalInfo; X long newpot; X X li->pos = newpos; X newpot = 0xffff * li->pos; X newpot /= li->nb - li->exists; X NewModifyProp(li->sld, win, req, pi->Flags, 0, newpot, X0, pi->VertBody, 1); X recalc_glist(li); X change = TRUE; X } X } X } X else X { X int i, pos = -1; X X for (i = 0; i < li->exists; i++) X if (gg == &(*li->glist)[i]) X { X pos = i; X break; X } X if (pos != -1) X { X ULONG secs, micros; X struct Node *scan; X X CurrentTime(&secs, µs); X if (li->current != -1) (*li->glist)[li->current - li->pos]. XFlags &= ~SELECTED; X li->current = li->pos + pos; X (*li->glist)[pos].Flags |= SELECTED; X change = TRUE; X li->buf[li->len - 1] = '\0'; X for (i = 0, scan = li->list->lh_Head; i < li->current; i++, X scan = scan->ln_Succ) X ; X strncpy(li->buf, scan->ln_Name, li->len - 1); X RefreshGList(li->strg, win, req, 1); X X ret = li->clickpos == li->current && DoubleClick(li->clicks Xecs, li->clickmics, secs, micros) ? 2 : 1; X li->clickpos = li->current; X li->clicksecs = secs; X li->clickmics = micros; X } X } X } X if (change) RefreshGList(&(*li->glist)[0], win, req, li->exists); X X return ret; X} X Xlong ChangeList(struct ListInfo *li, struct List *list, struct Requester *req, Xstruct Window *win) X{ X struct PropInfo *pi = (struct PropInfo *)li->sld->SpecialInfo; X long knobsize; X X free_ilist(li); X li->list = list; X if ((li->nb = build_ilist(li)) != -1) X { X if (li->current != -1) (*li->glist)[li->current - li->pos].Flags &= ~SE XLECTED; X X li->pos = 0; X li->current = -1; X li->clickpos = -1; X X if (li->nb == 0) X knobsize = 0xffff; X else X { X knobsize = 0xffff * li->exists; X knobsize /= li->nb; X } X NewModifyProp(li->sld, win, req, pi->Flags, 0, 0, 0, knobsize, 1); X X recalc_glist(li); X RefreshGList(&(*li->glist)[0], win, req, li->visible); X X return TRUE; X } X return FALSE; X} X Xstruct Gadget *ListStr(struct ListInfo *li) X{ X return li->strg; X} X Xstruct IntuiText *AddIntuiText(it, str, x, y, mem) Xstruct IntuiText **it; Xchar *str; Xlong x, y; Xstruct Memory *mem; X{ X struct IntuiText *intui = NULL; X X if (CheckFont(mem)) X { X intui = (struct IntuiText *)AllocRemember(&mem->Mem, sizeof(struct Intu XiText), MEMF_CLEAR); X if (intui) X { X intui->FrontPen = fore; intui->BackPen = back; X intui->DrawMode = mode; X intui->LeftEdge = x; intui->TopEdge = y; X intui->ITextFont = ta; X intui->IText = str; X X AppendText(it, intui); X } X } X X return(intui); X} X Xstruct Border *AddLineBorder(struct Border **border, long x0, long y0, long x1, X long y1, struct Memory *mem) X{ X BYTE *data; X struct Border *bb = NULL; X WORD *vert; X X data = (BYTE *)AllocRemember(&mem->Mem, sizeof(struct Border) + 2 * 2 * siz Xeof(WORD), MEMF_CLEAR); X if (data) { X bb = (struct Border *)data; X vert = (WORD *)(data + sizeof(struct Border)); X X bb->FrontPen = fore; bb->BackPen = back; X bb->DrawMode = mode; X bb->LeftEdge = 0; bb->TopEdge = 0; X bb->Count = 2; X bb->XY = vert; X X vert[0] = x0; vert[1] = y0; X vert[2] = x1; vert[3] = y1; X X AppendBorder(border, bb); X } X X return(bb); X} X Xstruct Border *AddRectBorder(border, x, y, w, h, mem) Xstruct Border **border; Xlong x, y, w, h; Xstruct Memory *mem; X{ X BYTE *data; X struct Border *bb = NULL; X WORD *vert; X X data = (BYTE *)AllocRemember(&mem->Mem, sizeof(struct Border) + 5 * 2 * siz Xeof(WORD), MEMF_CLEAR); X if (data) { X bb = (struct Border *)data; X vert = (WORD *)(data + sizeof(struct Border)); X X bb->FrontPen = fore; bb->BackPen = back; X bb->DrawMode = mode; X bb->LeftEdge = x; bb->TopEdge = y; X bb->Count = 5; X bb->XY = vert; X X vert[1 * 2 + 0] = w - 1; X vert[2 * 2 + 0] = w - 1; X vert[2 * 2 + 1] = h - 1; X vert[3 * 2 + 1] = h - 1; X X AppendBorder(border, bb); X } X X return(bb); X} X Xstruct Menu *AddMenu(struct Menu **ml, struct Screen *scr, char *text, long fla Xgs, struct Memory *mem) X{ X struct Screen look; X struct TextFont *scrfont; X struct Menu *menu = NULL, *prev; X X if (GetScreenData((char *)&look, sizeof(struct Screen), scr == NULL ? WBENC XHSCREEN : CUSTOMSCREEN, scr)) X if (scrfont = OpenDiskFont(look.Font)) X { X if (menu = (struct Menu *)AllocRemember(&mem->Mem, sizeof(struct Me Xnu), MEMF_CLEAR)) X { X menu->MenuName = text; X menu->Flags = flags; X menu->Height = scrfont->tf_YSize + 1; X menu->Width = scrfont->tf_XSize * strlen(text) + MENUMARGIN / 2 X; X X if (*ml == NULL) X { X menu->LeftEdge = 0; X *ml = menu; X } X else X { X for (prev = *ml; prev->NextMenu; prev = prev->NextMenu) ; X prev->NextMenu = menu; X menu->LeftEdge = prev->LeftEdge + prev->Width + MENUMARGIN; X X } X } X CloseFont(scrfont); X } X return menu; X} X X/* Assumes HIRES screen (for COMMWIDTH) */ Xstruct MenuItem *AddItem(struct Menu *menu, char *text, long flags, long mutex, X long cmd, long sub, struct Memory *mem) X{ X struct MenuItem *item = NULL, *prev; X struct IntuiText *it = NULL; X WORD width; X X if (AddIntuiText(&it, text, TEXTMARGIN / 2, TEXTGAP / 2, mem)) X { X if (item = (struct MenuItem *)AllocRemember(&mem->Mem, sizeof(struct Me XnuItem), MEMF_CLEAR)) X { X item->LeftEdge = 0; X width = IntuiTextLength(it) + TEXTMARGIN; X item->Flags = flags | ITEMTEXT; X item->Height = font->tf_YSize + TEXTGAP; X item->MutualExclude = mutex; X item->ItemFill = (APTR)it; X if (cmd) X { X item->Flags |= COMMSEQ; X width += COMMWIDTH + font->tf_XSize; X item->Command = cmd; X } X if (sub) X width += 2 * font->tf_XSize + TEXTMARGIN / 2; X X if (width < MINITEMWIDTH) width = MINITEMWIDTH; X X if (menu->FirstItem) X { X for (prev = menu->FirstItem; prev->NextItem; prev = prev->NextI Xtem) ; X item->TopEdge = prev->TopEdge + prev->Height; X prev->NextItem = item; X if (prev->Width > width) X item->Width = prev->Width; X else X for (prev = menu->FirstItem; prev; prev = prev->NextItem) X { X struct IntuiText *msg; X X if ((prev->Flags & ITEMTEXT) == 0) /* A rule */ X ((struct Image *)(prev->ItemFill))->Width = width - X RULEMARGIN; X else if ((msg = ((struct IntuiText *)(prev->ItemFill))- X>NextText) != NULL) /* A SubItem header */ X msg->LeftEdge += width - prev->Width; X X prev->Width = width; X } X } X else X { X menu->FirstItem = item; X item->TopEdge = 0; X item->Width = width; X } X if (sub && !AddIntuiText(&it, ".", item->Width - TEXTMARGIN / 2 - f Xont->tf_XSize, TEXTGAP / 2, mem)) X item = NULL; X } X } X return item; X} X X/* Assumes HIRES screen (for COMMWIDTH) */ Xstruct MenuItem *AddSub(struct MenuItem *item, char *text, long flags, long mut Xex, long cmd, struct Memory *mem) X{ X struct MenuItem *subitem = NULL, *prev; X struct IntuiText *it = NULL; X WORD width; X X if (AddIntuiText(&it, text, TEXTMARGIN / 2, TEXTGAP / 2, mem)) X { X if (subitem = (struct MenuItem *)AllocRemember(&mem->Mem, sizeof(struct X MenuItem), MEMF_CLEAR)) X { X subitem->LeftEdge = SUBX; X width = IntuiTextLength(it) + TEXTMARGIN; X subitem->Flags = flags | ITEMTEXT; X subitem->Height = font->tf_YSize + TEXTGAP; X subitem->MutualExclude = mutex; X subitem->ItemFill = (APTR)it; X if (cmd) X { X subitem->Flags |= COMMSEQ; X width += COMMWIDTH + font->tf_XSize; X subitem->Command = cmd; X } X if (width < MINITEMWIDTH) width = MINITEMWIDTH; X X if (item->SubItem) X { X for (prev = item->SubItem; prev->NextItem; prev = prev->NextIte Xm) ; X subitem->TopEdge = prev->TopEdge + prev->Height; X prev->NextItem = subitem; X if (prev->Width > width) X subitem->Width = prev->Width; X else X for (prev = item->SubItem; prev; prev = prev->NextItem) X prev->Width = width; X } X else X { X item->SubItem = subitem; X subitem->TopEdge = font->tf_YSize / 2 + 1; X subitem->Width = width; X } X } X } X return subitem; X} X/* Inspired by Stuart Ferguson's code */ Xstruct MenuItem *AddRule(struct Menu *menu, struct Memory *mem) X{ X struct MenuItem *item = NULL, *prev; X struct Image *img; X X if ((img = (struct Image *)AllocRemember(&mem->Mem, sizeof(struct Image), M XEMF_CLEAR)) && X (item = (struct MenuItem *)AllocRemember(&mem->Mem, sizeof(struct MenuI Xtem), MEMF_CLEAR))) X { X item->LeftEdge = 0; X item->Flags = ITEMENABLED | HIGHNONE; X item->Height = RULEGAP + RULEHEIGHT; X item->MutualExclude = 0; X item->ItemFill = (APTR)img; X X if (menu->FirstItem) X { X for (prev = menu->FirstItem; prev->NextItem; prev = prev->NextItem) X ; X item->TopEdge = prev->TopEdge + prev->Height; X prev->NextItem = item; X item->Width = prev->Width; X } X else X { X menu->FirstItem = item; X item->TopEdge = 0; X item->Width = MINITEMWIDTH; X } X img->LeftEdge = RULEMARGIN / 2; X img->TopEdge = RULEGAP / 2; X img->Width = item->Width - RULEMARGIN; X img->Height = RULEHEIGHT; X img->Depth = depth; X img->ImageData = NULL; X img->PlanePick = 0; X img->PlaneOnOff = fore; X } X return item; X} X Xboolean CheckFont(mem) Xstruct Memory *mem; X{ X struct FontNode *fn; X X if (ta == NULL) fontopen = TRUE; X if (!fontopen) X { X font = (struct TextFont *)OpenDiskFont(ta); X if (font) X { X fn = (struct FontNode *)AllocRemember(&mem->Mem, sizeof(struct Font XNode), MEMF_CLEAR); X if (fn) X { X fn->font = font; X AddHead((struct List *)&mem->Fonts, (struct Node *)fn); X fontopen = TRUE; X } X else CloseFont(font); X } X } X X return(fontopen); X} X Xvoid AppendGadget(gl, gg) Xstruct Gadget **gl, *gg; X{ X struct Gadget *gadg; X X if (*gl == NULL) *gl = gg; X else X { X gadg = *gl; X while (gadg->NextGadget) gadg = gadg->NextGadget; X gadg->NextGadget = gg; X } X} X Xvoid AppendBorder(bl, bb) Xstruct Border **bl, *bb; X{ X struct Border *bord; X X if (*bl == NULL) *bl = bb; X else X { X bord = *bl; X while (bord->NextBorder) bord = bord->NextBorder; X bord->NextBorder = bb; X } X} X Xvoid AppendText(itl, txt) Xstruct IntuiText **itl, *txt; X{ X struct IntuiText *intui; X X if (*itl == NULL) *itl = txt; X else X { X intui = *itl; X while (intui->NextText) intui = intui->NextText; X intui->NextText = txt; X } X} X X#define Line(rp, x1, y1, x2, y2) { Move((rp), (x1), (y1)); Draw((rp), (x2), (y2 X)); } X Xvoid DrawRect(rp, x, y, w, h) Xstruct RastPort *rp; Xlong x, y, w, h; X{ X Move(rp, x, y); X Draw(rp, x + w - 1, y); X Draw(rp, x + w - 1, y + h - 1); X Draw(rp, x, y + h - 1); X Draw(rp, x, y); X} X Xvoid DrawRoundedRect(rp, x, y, w, h) Xstruct RastPort *rp; Xlong x, y, w, h; X{ X int x2 = x + w - 1, y2 = y + h - 1; X X Line(rp, x + 5, y, x2 - 5, y); Line(rp, x + 5, y2, x2 - 5, y2); X Line(rp, x, y + 5, x, y2 - 4); Line(rp, x2, y + 5, x2, y2 - 4); X WritePixel(rp, x + 4, y + 1); WritePixel(rp, x + 3, y + 1); WritePixel(rp, Xx + 2, y + 2); WritePixel(rp, x + 1, y + 3); WritePixel(rp, x + 1, y + 4); X WritePixel(rp, x + 4, y2 - 1); WritePixel(rp, x + 3, y2 - 1); WritePixel(rp X, x + 2, y2 - 2); WritePixel(rp, x + 1, y2 - 3); WritePixel(rp, x + 1, y2 - 4); X WritePixel(rp, x2 - 4, y + 1); WritePixel(rp, x2 - 3, y + 1); WritePixel(rp X, x2 - 2, y + 2); WritePixel(rp, x2 - 1, y + 3); WritePixel(rp, x2 - 1, y + 4); X WritePixel(rp, x2 - 4, y2 - 1); WritePixel(rp, x2 - 3, y2 - 1); WritePixel( Xrp, x2 - 2, y2 - 2); WritePixel(rp, x2 - 1, y2 - 3); WritePixel(rp, x2 - 1, y2 - X 4); X} X Xvoid FillRoundedRect(rp, x, y, w, h) Xstruct RastPort *rp; Xlong x, y, w, h; X{ X int x2 = x + w - 1, y2 = y + h - 1; X X RectFill(rp, x, y + 5, x2, y2 - 5); X Line(rp, x + 1, y + 4, x2 - 1, y + 4); Line(rp, x + 1, y + 3, x2 - 1, y + 3 X); Line(rp, x + 2, y + 2, x2 - 2, y + 2); Line(rp, x + 4, y + 1, x2 - 4, y + 1); X X Line(rp, x + 1, y2 - 4, x2 - 1, y2 - 4); Line(rp, x + 1, y2 - 3, x2 - 1, y2 X - 3); Line(rp, x + 2, y2 - 2, x2 - 2, y2 - 2); Line(rp, x + 4, y2 - 1, x2 - 4, Xy2 - 1); X} X SHAR_EOF echo "extracting gadgets.h" sed 's/^X//' << \SHAR_EOF > gadgets.h X/* Routines to create various types of gadgets, menus, etc X Could do with a few comments and some documentation ... X This code is placed in the public domain. X David Gay, 1989. X*/ X X#ifndef GADGETS_H X#define GADGETS_H X Xtypedef long boolean; X Xstruct Memory *NewMemory(void); Xvoid Free(struct Memory *); Xvoid ModSys(long, long, long, struct TextAttr *); Xvoid SetDepth(long); X Xstruct Requester *InitReq(long, long, long, long, struct Memory *); Xboolean SetReqBorder(struct Requester *, long, struct Memory *); Xvoid SetReqGadgets(struct Requester *, struct Gadget *); Xvoid SetReqText(struct Requester *, struct IntuiText *); X Xstruct Gadget *AddBox(struct Gadget **, long, char *, long, long, long, long, l Xong, long, long, struct Memory *); Xstruct Gadget *AddOption(struct Gadget **, long, char *, long, long, long, long X, long, long, long, struct Memory *); Xstruct Gadget *AddRadio(struct Gadget **, long, char *, long, long, long, long, X long, long, long, long, struct Memory *); Xstruct Gadget *AddText(struct Gadget **gl, long id, char *text, long above, cha Xr *buf, X long maxlen, long undo, long flags, long act, X long x, long y, long w, long h, long noborder, struct Me Xmory *mem); Xstruct Gadget *AddSlider(struct Gadget **gl, long id, long act, X long x, long y, long w, long h, long vert, X long knobsize, struct Memory *mem); Xstruct ListInfo *AddList(struct Gadget **gl, long id, char *text, struct List * Xlist, char *buf, long len, long flags, long act, long x, long y, long w, long h, X long noborder, struct Memory *mem); Xlong ModifyList(struct Gadget *gg, struct Requester *req, struct Window *win, l Xong up); Xlong ChangeList(struct ListInfo *li, struct List *list, struct Requester *req, Xstruct Window *win); Xstruct Gadget *ListStr(struct ListInfo *li); Xvoid AppendGadget(struct Gadget **, struct Gadget *); X Xstruct IntuiText *AddIntuiText(struct IntuiText **, char *, long, long, struct XMemory *); Xvoid AppendText(struct IntuiText **, struct IntuiText *); X Xstruct Border *AddLineBorder(struct Border **, long, long, long, long, struct M Xemory *); Xstruct Border *AddRectBorder(struct Border **, long, long, long, long, struct M Xemory *); Xvoid AppendBorder(struct Border **, struct Border *); X Xvoid DrawRect(struct RastPort *, long, long, long, long); Xvoid DrawRoundedRect(struct RastPort *, long, long, long, long); Xvoid FillRoundedRect(struct RastPort *, long, long, long, long); X Xstruct Menu *AddMenu(struct Menu **ml, struct Screen *scr, char *text, long fla Xgs, struct Memory *mem); Xstruct MenuItem *AddItem(struct Menu *menu, char *text, long flags, long mutex, X long cmd, long sub, struct Memory *mem); Xstruct MenuItem *AddRule(struct Menu *menu, struct Memory *mem); Xstruct MenuItem *AddSub(struct MenuItem *item, char *text, long flags, long mut Xex, long cmd, struct Memory *mem); X X#endif X SHAR_EOF echo "End of archive 2 (of 7)" # if you want to concatenate archives, remove anything after this line exit