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