page%swap@Sun.COM (Bob Page) (11/13/89)
Submitted-by: dg3i+@andrew.cmu.edu (David Gay) Posting-number: Volume 89, Issue 208 Archive-name: applications/graph.5 # 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: # grph.h # label.c # list.c # list.h # lmkfile # lmko # lnk # lnko # make.shar # mv2dir # This is archive 5 of a 7-part kit. # This archive created: Sun Nov 12 18:23:31 1989 echo "extracting grph.h" sed 's/^X//' << \SHAR_EOF > grph.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/* Routines for handling graphs */ X#ifndef GRPH_H X#define GRPH_H X X#include "list.h" X#include "user/gadgets.h" X X/* Various string lengths */ X#define TITLELEN 80 X#define GNAMELEN 20 X X/* Store information on each axis */ Xstruct ax { X double min, max; X double ax, cstep; /* Axes positions, ax is the position of this axis on the X other */ X /* cstep: interval for ticks */ X int every; /* Frequency of numbering on ticks */ X int log; /* log scale ? */ X}; X X/* Information on coordinate system */ Xstruct axes { X struct ax x, y; X double ratio; /* y / x, NOVAL for none (>0 !!) */ X int polar : 1; /* Not used */ X int ok : 1; X}; X X/* User interface state */ Xstruct state { X int select_mode : 1; X int mouse : 1; /* mouse moves expected */ X double x, y; /* mouse pos. */ X struct object *current; X}; X X/* All information needed for user interface */ Xstruct io { X UWORD nextmenu; /* For menu selections */ X struct RWindow *rw; /* Currently selected output */ X int dpmx, dpmy; /* Scale (in dots per meter) of output */ X struct Window *win; /* Window, and assoc. info */ X WORD oldwidth, oldheight; X struct Gadget *gadgets; X struct Menu *menu; X struct Memory *mem; X char title[TITLELEN]; X struct TextFont *digits; /* Font for displaying digits on graph */ X}; X X/* A graph, made up from the above components */ X Xstruct graph { X node node; X int ok : 1; X int saved : 1; X char name[GNAMELEN]; X struct io io; X list o_list; /* List of objects in graph */ X struct axes a; X struct state s; X}; X X/* Open font name, in pts points (use graph scale). Takes nearest size */ Xstruct TextFont *open_font(struct graph *g, char *name, int pts, int style, int X flags); X/* Convert size in inches to dots in selected output */ Xint xinch2dots(struct graph *g, double x); Xint yinch2dots(struct graph *g, double y); X X/* objects */ Xstruct object *add_object(struct graph *g, struct object *o); Xvoid remove_object(struct graph *g, struct object *o); Xvoid select_object(struct graph *g, struct object *o); Xvoid deselect(struct graph *g); X X/* User has used mouse, do any necessary housekeeping (move, select objects, et Xc) */ Xvoid mouse_down(struct graph *g, WORD sx, WORD sy); Xvoid mouse_move(struct graph *g, WORD sx, WORD sy); Xvoid mouse_up(struct graph *g, WORD sx, WORD sy); X X/* Ask user to : */ Xstruct object *choose_object(struct graph *g, char *op); /* Select object by na Xme */ Xvoid enter_limits(struct graph *g); /* Define coord system */ Xvoid enter_axes(struct graph *g); /* Choose axes display options */ X X/* Change graph: */ Xint set_dpm(struct graph *g, int dpmx, int dpmy); /* set new scale (in dpm) */ Xvoid set_thin(struct graph *g, struct RastPort *rp); /* Use thin lines */ Xvoid set_pensize(struct graph *g, struct RastPort *rp, double ptsize); /* Use l Xines ptsize points wide */ Xvoid set_mode(struct graph *g, int newmode); /* Select select/point mode */ Xvoid set_scale(struct graph *g); /* Window size has changed */ Xvoid zoom_in(struct graph *g, double x0, double y0, double x1, double y1); /* S Xet new coord limits */ Xvoid zoom_factor(struct graph *g, double factor); /* Zoom in by a factor */ Xvoid center_graph(struct graph *g, double x, double y); /* Recenter around poin Xt */ X X/* Output routines: */ Xvoid draw_graph(struct graph *g, int allow_mes); /* Draw graph */ Xvoid refresh_graph(struct graph *g, int allow_mes, struct Region *ref); /* Redr Xaw inside region ref only */ Xstruct Region *full_refresh(struct graph *g); /* Return a region covering the w Xhole graph */ Xvoid set_title(struct graph *g); /* Change graph title */ Xvoid prt_graph(struct graph *g); /* Output graph to printer */ Xvoid iff_todisk(struct graph *g); /* Output graph as an ILBM file */ X X/* Manipulate graphs : */ Xstruct graph *load_graph(struct graph *from, FILE *f); Xint save_graph(struct graph *g, FILE *f); Xstruct graph *new_graph(struct graph *from); /* from allows you to display mess Xages ... (NULL if none) */ Xvoid delete_graph(struct graph *g); X X/* Global init/cleanup. Must be called */ Xint init_grph(void); Xvoid cleanup_grph(void); X X#endif X SHAR_EOF echo "extracting label.c" sed 's/^X//' << \SHAR_EOF > label.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#include <exec/types.h> X#include <intuition/intuition.h> X#include <graphics/text.h> X#include <string.h> X#include <limits.h> X X#include "object.h" X#include "object/default.h" X#include "file.h" X#include "graph.h" X#include "uio.h" X#include "coords.h" X#include "grph.h" X#include "user/gadgets.h" X#include "graphics.h" X#include "tracker.h" X X#include <proto/exec.h> X#include <proto/intuition.h> X#include <proto/graphics.h> X X#define LABELLEN 256 X#define LABELHEIGHT 10 X#define LABELFONT "topaz.font" X#define FONTLIST 2 X X/* The various justification possibilities */ Xenum justify { top, centre, bottom }; X X/* (private) class label, inherits from object */ Xstruct label X{ X struct object o; X char text[LABELLEN]; /* What to display, \ for newlines */ X BYTE colour; X char fname[FONTLEN]; /* font name */ X int fheight; /* font height */ X double x, y; /* text position */ X double dx, dy; /* offset from position, in inches */ X enum justify jx, jy; /* justification (x & y axes) */ X X char selected; X /* Temp, etc vars */ X char broken[LABELLEN]; /* Text, separated into lines (separated by NULLs) X */ X int nblines; /* number of lines */ X struct Rectangle extent; /* Size of rectangle taken by text */ X int bw, bh; /* Size of bitmap (for moving) */ X struct Rectangle lims; /* Rectangle taken up on screen */ X int x0, y0; /* x & y in screen coords (wthout ddx, ddy) */ X struct TextFont *font, *newfont; /* the font (newfont for inform/confirm) * X/ X double oldx, oldy; /* position before move */ X int ddx, ddy; /* dx, dy in pixels */ X struct Region *ref; X struct RastPort bkgd; /* Rastport & bitmap for moves */ X struct BitMap bkgd_bm; X}; X X/*-------------------------------------------------------------------------*/ X/* label class implementation */ X/*-------------------------------------------------------------------------*/ X X/* Allocates bitmap for saving background while moving */ X/* Assumes 2 bit planes */ Xstatic int alloc_bkgd_label(struct label *this) X{ X BYTE *data; X X if (data = AllocMem(2 * RASSIZE(this->bw, this->bh), MEMF_CHIP)) X { X InitBitMap(&this->bkgd_bm, 2, this->bw, this->bh); X this->bkgd_bm.Planes[0] = (PLANEPTR)data; X this->bkgd_bm.Planes[1] = (PLANEPTR)(data + RASSIZE(this->bw, this->bh) X); X InitRastPort(&this->bkgd); X this->bkgd.BitMap = &this->bkgd_bm; X } X return data != 0; X} X X/* Frees bitmap alloced above */ Xstatic void free_bkgd_label(struct label *this) X{ X FreeMem(this->bkgd_bm.Planes[0], 2 * RASSIZE(this->bw, this->bh)); X} X X/* Save scrren background into temp space */ Xstatic void save_bkgd_label(struct label *this) X{ X ClipBlit(this->o.g->io.rw->rp, this->lims.MinX, this->lims.MinY, &this->bkg Xd, 0, 0, this->bw, this->bh, 0xc0); X} X X/* Copies saved background back to the screen */ Xstatic void restore_bkgd_label(struct label *this) X{ X ClipBlit(&this->bkgd, 0, 0, this->o.g->io.rw->rp, this->lims.MinX, this->li Xms.MinY, this->bw, this->bh, 0xc0); X} X X/* Do all the precalculations */ Xstatic void setup_label(struct label *this) X{ X struct TextFont *font = this->font; X char *srch, *nl; X X this->ddx = xinch2dots(this->o.g, this->dx); X this->ddy = yinch2dots(this->o.g, this->dy); X X /* Break up label & calculate rectangle used */ X srch = strcpy(this->broken, this->text); X this->nblines = 0; X this->extent.MaxX = 0; X this->extent.MinX = INT_MAX; X do X { X struct TextExtent te; X X nl = strchr(srch, '\\'); X X if (nl && *(nl + 1) == '\\') /* add single slash */ X movmem(nl + 1, nl, LABELLEN - (nl - this->broken) - 1); X else X { X this->nblines++; X if (nl) *nl = '\0'; X /* Check space for this line */ X TextExtent(srch, font, &te); X if (te.te_Extent.MaxX > this->extent.MaxX) this->extent.MaxX = te.t Xe_Extent.MaxX; X if (te.te_Extent.MinX < this->extent.MinX) this->extent.MinX = te.t Xe_Extent.MinX; X } X srch = nl + 1; X } while (nl); X X this->extent.MinY = 0; X this->extent.MaxY = this->nblines * font->tf_YSize; X this->bw = this->extent.MaxX - this->extent.MinX + 1; X this->bh = this->extent.MaxY - this->extent.MinY + 1; X} X X/* Work out rectangle used by text */ Xstatic void calc_rect(struct label *this) X{ X struct graph *g = this->o.g; X struct RWindow *rw = g->io.rw; X int delta, x0, y0; X X /* Find origin */ X /* Default */ X x0 = (this->x0 = ftol(rw->sx(rw, this->x))) + this->ddx; X y0 = (this->y0 = ftol(rw->sy(rw, this->y))) + this->ddy; X X /* Adjust for justification */ X switch (this->jx) X { X case centre: X x0 -= this->bw / 2; X break; X case bottom: /* right */ X x0 -= this->bw; X break; X } X switch (this->jy) X { X case centre: X y0 -= this->bh / 2; X break; X case bottom: /* right */ X y0 -= this->bh; X break; X } X /* Extent defines actual rectangle */ X this->lims.MinX = x0 + this->extent.MinX; X this->lims.MaxX = x0 + this->extent.MaxX; X this->lims.MinY = y0 + this->extent.MinY; X this->lims.MaxY = y0 + this->extent.MaxY; X X /* Make sure that it stays visible */ X /* Could one reduce the number of flops ? */ X /* Idea: Generalise inform/confirm */ X if ((delta = ftol(rw->sx(rw, g->a.x.min)) - this->lims.MinX) > 0 || X (delta = ftol(rw->sx(rw, g->a.x.max)) - this->lims.MaxX) < 0) X { X this->x0 += delta; X this->lims.MinX += delta; X this->lims.MaxX += delta; X } X if ((delta = ftol(rw->sy(rw, g->a.y.max)) - this->lims.MinY) > 0 || X (delta = ftol(rw->sy(rw, g->a.y.min)) - this->lims.MaxY) < 0) X { X this->y0 += delta; X this->lims.MinY += delta; X this->lims.MaxY += delta; X } X} X X/* Add the current position to the region */ Xstatic void add_region(struct label *this) X{ X if (!this->ref) this->ref = NewRegion(); X if (this->ref && !OrRectRegion(this->ref, &this->lims)) X { X DisposeRegion(this->ref); X this->ref = NULL; X } X if (!this->ref) nomem(this->o.g->io.win); X} X X/* Were we clicked on ? */ Xstatic int down_label(struct label *this) X{ X struct graph *g = this->o.g; X WORD sx = ftol(g->io.rw->sx(g->io.rw, g->s.x)); X WORD sy = ftol(g->io.rw->sy(g->io.rw, g->s.y)); X int inside; X X calc_rect(this); X inside = sx >= this->lims.MinX && sx <= this->lims.MaxX && X sy >= this->lims.MinY && sy <= this->lims.MaxY; X if (inside) X { X /* Setup internal info for move */ X this->o.mx = sx - this->x0; X this->o.my = sy - this->y0; X if (alloc_bkgd_label(this)) X { X save_bkgd_label(this); X if (this->selected) X { X SetDrMd(&this->bkgd, COMPLEMENT); X RectFill(&this->bkgd, 0, 0, this->bw - 1, this->bh - 1); X } X this->ref = NULL; X add_region(this); /* Original pos. will probably need refreshing */ X X this->oldx = this->x; this->oldy = this->y; X } X else /* failed, no mem */ X { X nomem(this->o.g->io.win); X inside = FALSE; X } X } X return inside; X} X X/* Reverse label's rectangle (eg for selection) */ Xstatic void reverse_label(struct label *this) X{ X struct RastPort *rp = this->o.g->io.rw->rp; X X SetDrMd(rp, COMPLEMENT); X RectFill(rp, this->lims.MinX, this->lims.MinY, this->lims.MaxX, this->lims. XMaxY); X} X X/* Draw label */ Xstatic void draw_label(struct label *this, int allow_mes) X{ X struct graph *g = this->o.g; X struct RastPort *rp = g->io.rw->rp; X char *str; X int i; X X calc_rect(this); X SetAPen(rp, this->colour); X SetDrMd(rp, JAM1); X SetFont(rp, this->font); X X /* Draw all the lines of text */ X Move(rp, this->lims.MinX - this->extent.MinX, this->lims.MinY - this->exten Xt.MinY + this->font->tf_Baseline); X for (str = this->broken, i = this->nblines; i; i--) X { X int l = strlen(str); X X Text(rp, str, l); X Move(rp, this->lims.MinX - this->extent.MinX, rp->cp_y + this->font->tf X_YSize); X X str += l + 1; /* Onto next string */ X } X X if (this->selected) reverse_label(this); X} X X/* We're now selected */ Xstatic void select_label(struct label *this) X{ X this->selected = TRUE; X if (this->o.g->ok && this->o.g->io.rw) X { X calc_rect(this); X reverse_label(this); X } X} X X/* A quick walk around town ... */ Xstatic void move_label(struct label *this) X{ X restore_bkgd_label(this); /* erase label */ X this->x = this->o.g->s.x; X this->y = this->o.g->s.y; X calc_rect(this); X save_bkgd_label(this); /* Save background */ X draw_label(this, TRUE); /* & draw at new pos */ X} X X/* Mouse buttonb released, refresh needed ? */ Xstatic struct Region *up_label(struct label *this) X{ X restore_bkgd_label(this); /* Restore at last pos */ X this->x = this->o.g->s.x; X this->y = this->o.g->s.y; X calc_rect(this); X free_bkgd_label(this); X if (this->x != this->oldx || this->y != this->oldy) /* we moved */ X { X add_region(this); /* Refresh at new pos */ X return this->ref; X } X else X { X draw_label(this, TRUE); /* Just redraw, no refresh needed */ X DisposeRegion(this->ref); X return NULL; X } X} X X/* End of selection, unhighlight */ Xstatic struct Region *deselect_label(struct label *this) X{ X this->selected = FALSE; X if (this->o.g->ok && this->o.g->io.rw) X { X calc_rect(this); X reverse_label(this); X } X return NULL; X} X X/* Handle edit requester */ Xint edit_handler(struct Gadget *gg, ULONG class, struct Requester *req, struct Xgraph *g) X{ X if (gg->GadgetID == FONTLIST) /* User played with font list */ X { X if (ModifyList(gg, req, req->RWindow, class == GADGETUP) == 2) X { X /* Double click -> exit */ X EndRequest(req, req->RWindow); X return TRUE; X } X return FALSE; X } X else return std_ghandler(gg, class, req, g); X} X X/* Allow user to edit us */ Xstatic int edit_label(struct label *this, struct Region **ref) X{ X struct Requester *req; X struct Memory *m; X struct Gadget *gl = NULL; X int ret = FALSE; X char text[LABELLEN], dx[NBLEN], dy[NBLEN], x[NBLEN], y[NBLEN], fname[FONTLE XN], fheight[INTLEN], colour[INTLEN]; X struct Gadget *leftg, *ctrxg, *rightg, *topg, *ctryg, *bottomg; X X this->ref = NULL; X X /* Create requester */ X strcpy(text, this->text); X double2str(dx, this->dx); X double2str(dy, this->dy); X double2str(x, this->x); X double2str(y, this->y); X strcpy(fname, this->fname); X remfont(fname); X int2str(fheight, this->fheight); X int2str(colour, this->colour); X X if ((m = NewMemory()) && X (req = InitReq(50, 15, 395, 166, m)) && X SetReqBorder(req, 1, m) && X AddIntuiText(&req->ReqText, "Edit Label", 158, 6, m) && X AddText(&gl, 0, "Text ", FALSE, text, LABELLEN, TRUE, 0, RELVERIFY, 49, X 20, 335, 10, TRUE, m) && X AddText(&gl, 0, "X = ", FALSE, x, NBLEN, TRUE, 0, RELVERIFY, 43, 40, 56 X, 10, TRUE, m) && X AddText(&gl, 0, "dX = ", FALSE, dx, NBLEN, TRUE, 0, RELVERIFY, 147, 40, X 56, 10, TRUE, m) && X (leftg = AddRadio(&gl, 0, "left", TRUE, SELECTED * (this->jx == top), R XELVERIFY, 16 + 32, 210, 40, 10, 10, m)) && X (ctrxg = AddRadio(&gl, 0, "centre", TRUE, SELECTED * (this->jx == centr Xe), RELVERIFY, 8 + 32, 260, 40, 10, 10, m)) && X (rightg = AddRadio(&gl, 0, "right", TRUE, SELECTED * (this->jx == botto Xm), RELVERIFY, 16 + 8, 326, 40, 10, 10, m)) && X AddText(&gl, 0, "Y = ", FALSE, y, NBLEN, TRUE, 0, RELVERIFY, 43, 60, 56 X, 10, TRUE, m) && X AddText(&gl, 0, "dY = ", FALSE, dy, NBLEN, TRUE, 0, RELVERIFY, 147, 60, X 56, 10, TRUE, m) && X (topg = AddRadio(&gl, 0, "top", TRUE, SELECTED * (this->jy == top), REL XVERIFY, 512 + 1024, 210, 60, 10, 10, m)) && X (ctryg = AddRadio(&gl, 0, "centre", TRUE, SELECTED * (this->jy == centr Xe), RELVERIFY, 256 + 1024, 260, 60, 10, 10, m)) && X (bottomg = AddRadio(&gl, 0, "bottom", TRUE, SELECTED * (this->jy == bot Xtom), RELVERIFY, 256 + 512, 326, 60, 10, 10, m)) && X AddText(&gl, 0, "Colour ", FALSE, colour, INTLEN, TRUE, 0, RELVERIFY, 2 X36, 80, 32, 10, TRUE, m) && X AddText(&gl, 0, "Size ", FALSE, fheight, INTLEN, TRUE, 0, RELVERIFY, 22 X0, 150, 32, 10, TRUE, m) && X AddList(&gl, FONTLIST, "Font", &flist, fname, FONTLEN, 0, RELVERIFY, 11 X, 80, 160, 80, TRUE, m) && X AddBox(&gl, TRUE, "Ok", 0, RELVERIFY | ENDGADGET, 255, 100, 65, 15, FAL XSE, m) && X AddBox(&gl, FALSE, "Cancel", 0, RELVERIFY | ENDGADGET, 255, 130, 65, 15 X, FALSE, m)) X { X SetReqGadgets(req, gl); X if (ret = DoRequest(req, this->o.g, edit_handler) && *stpblk(text) != ' X\0') X { X /* Update label */ X double new; X int fh; X struct TextFont *newfont; X X add_region(this); /* Refresh needed at old pos */ X X /* New justification, etc */ X if ((this->colour = str2int(colour)) == INOVAL) this->colour = 1; X strcpy(this->text, text); X if ((new = str2double(x)) != NOVAL) this->x = new; X if ((new = str2double(y)) != NOVAL) this->y = new; X if ((this->dx = str2double(dx)) == NOVAL) this->dx = 0.0; X if ((this->dy = str2double(dy)) == NOVAL) this->dy = 0.0; X X if (leftg->Flags & SELECTED) this->jx = top; X else if (ctrxg->Flags & SELECTED) this->jx = centre; X else this->jx = bottom; X X if (topg->Flags & SELECTED) this->jy = top; X else if (ctryg->Flags & SELECTED) this->jy = centre; X else this->jy = bottom; X X /* Check font */ X addfont(fname); X if ((fh = str2int(fheight)) == INOVAL || fh <= 0) fh = LABELHEIGHT; X X if (newfont = open_font(this->o.g, fname, fh, 0, 0)) X { X strcpy(this->fname, fname); X this->fheight = fh; X CloseFont(this->font); X this->font = newfont; X } X else message(this->o.g, "Invalid font specified", (char *)NULL); X X /* Do precalculation */ X setup_label(this); X calc_rect(this); X add_region(this); /* New position needs refreshing */ X } X } X Free(m); X *ref = this->ref; X return ret; X} X X/* No vsriables used in labels */ Xint var_change_label(struct label *this, char *name) X{ X return FALSE; X} X X/* Confirm changes made */ Xstatic void confirm_label(struct label *this, int ok) X{ X if (ok) X { X CloseFont(this->font); X this->font = this->newfont; X setup_label(this); X } X else CloseFont(this->newfont); /* failed */ X} X X/* Resolution has changed */ Xstatic int inform_label(struct label *this, int ok) X{ X if (this->newfont = open_font(this->o.g, this->fname, this->fheight, 0, 0)) X X return TRUE; X X message(this->o.g, "Couldn't open font", (char *)NULL); X return FALSE; X X} X X/* Write label to file */ Xstatic int save_label(struct label *this, FILE *f) X{ X short tag = LABEL_TAG; X short end = LABEL_END; X X return WRITE(f, tag) && X WRITE(f, this->text) && X WRITE(f, this->colour) && X WRITE(f, this->fname) && X WRITE(f, this->fheight) && X WRITE(f, this->x) && X WRITE(f, this->y) && X WRITE(f, this->dx) && X WRITE(f, this->dy) && X WRITE(f, end); X} X X/* free label */ Xstatic struct Region *delete_label(struct label *this) X{ X struct Region *ref; X X /* Label's position will need refreshing */ X this->ref = NULL; X if (this->o.g->ok && this->o.g->io.rw) add_region(this); X ref = this->ref; X X if (this->font) CloseFont(this->font); X FreeMem(this, sizeof(struct label)); X X return ref; X} X X/* Initialise label structure */ Xstatic struct label *make_label(struct graph *g) X{ X struct label *this = AllocMem(sizeof(struct label), 0L); X const static struct label def_l = { X { X { NULL }, X NULL, "", TRUE, 0, 0, X (void *)delete_label, (void *)select_label, (void *)deselect_label, X X (void *)down_label, (void *)move_label, (void *)up_label, X (void *)edit_label, (void *)draw_label, (void *)notdone, X (void *)notdone, (void *)var_change_label, (void *)save_label, X (void *)inform_label, (void *)confirm_label X }, X "", 1, LABELFONT, LABELHEIGHT, NOVAL, NOVAL, 0.0, 0.0, FALSE X }; X X if (this) X { X *this = def_l; X this->o.g = g; X /* Default font *must* be there */ X if (this->font = open_font(g, LABELFONT, LABELHEIGHT, 0, 0)) X { X return this; X } X else X message(g, "Couldn't open font", (char *)NULL); X FreeMem(this, sizeof(struct label)); X } X else X message(g, "No memory !", (char *)NULL); X return NULL; X} X X/* Load label from file */ Xstruct label *load_label(struct graph *g, FILE *f) X{ X struct label *this = make_label(g); X X if (this) X { X short tag; X X if (READ(f, this->text) && X READ(f, this->colour) && X READ(f, this->fname) && X READ(f, this->fheight) && X READ(f, this->x) && X READ(f, this->y) && X READ(f, this->dx) && X READ(f, this->dy) && X READ(f, tag) && X tag == LABEL_END) X { X struct TextFont *newfont; X X if (newfont = open_font(this->o.g, this->fname, this->fheight, 0, 0 X)) X { X CloseFont(this->font); X this->font = newfont; X } X else /* Lack of font isn't drastic */ X { X message(g, "No such font available", this->fname, (char *)NULL) X; X strcpy(this->fname, LABELFONT); X } X setup_label(this); X return this; X } X delete_label(this); X } X return NULL; X} X X/* Create a new label, at pos. (x,y). Asks user for text */ Xstruct label *new_label(struct graph *g, double x, double y) X{ X struct label *this = make_label(g); X X if (this) X { X /* Create requester */ X struct Requester *req; X struct Memory *m; X struct Gadget *gl = NULL; X int ret = FALSE; X X this->x = x; X this->y = y; X X if ((m = NewMemory()) && X (req = InitReq(50, 20, 160, 65, m)) && X SetReqBorder(req, 1, m) && X AddIntuiText(&req->ReqText, "Add Label", 44, 6, m) && X AddText(&gl, TRUE, "Text ", FALSE, this->text, LABELLEN, TRUE, 0, R XELVERIFY | ENDGADGET, 49, 20, 100, 10, TRUE, m) && X AddBox(&gl, TRUE, "Ok", 0, RELVERIFY | ENDGADGET, 8, 40, 65, 15, FA XLSE, m) && X AddBox(&gl, FALSE, "Cancel", 0, RELVERIFY | ENDGADGET, 88, 40, 65, X15, FALSE, m)) X { X SetReqGadgets(req, gl); X if (ret = DoRequest(req, g, std_ghandler) && *stpblk(this->text) != X '\0') X { X /* Create it */ X setup_label(this); X if (g->ok && g->io.rw) draw_label(this, TRUE); X Free(m); X return this; X } X } X Free(m); X delete_label(this); X } X else X message(g, "No memory !", (char *)NULL); X return NULL; X} X SHAR_EOF echo "extracting list.c" sed 's/^X//' << \SHAR_EOF > list.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#include <exec/types.h> X#include <stddef.h> X#include "list.h" X#include "tracker.h" X X/* Free all elements in list (each of size size) */ Xvoid free_list(list *l, size_t size) X{ X node *scan, *next; X X for (scan = first(l); next = succ(scan); scan = next) X FreeMem(scan, size); X X /* Be safe */ X new_list(l); X} X SHAR_EOF echo "extracting list.h" sed 's/^X//' << \SHAR_EOF > list.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/* Simplify and "genericize" list operations */ X#ifndef LIST_H X#define LIST_H X X#include <exec/nodes.h> X#include <exec/lists.h> X#include <stddef.h> X X/* The standard list elements */ Xtypedef struct MinList list; Xtypedef struct MinNode node; Xtypedef struct List tlist; /* Typed list */ Xtypedef struct Node tnode; /* Typed (&named) node */ X X#define new_list(list) NewList((tlist *)(list)) X X#define add_head(list, node) AddHead((tlist *)(list), (tnode *)(node)) X#define add_tail(list, node) AddTail((tlist *)(list), (tnode *)(node)) X#define rem_head(list) (void *)RemHead((tlist *)(list)) X#define rem_tail(list) (void *)RemTail((tlist *)(list)) X X#define remove(node) Remove((tnode *)(node)) X#define insert(list, node, pos) Insert((tlist *)(list), (tnode *)(node), (tnode X *)(pos)) X X#define first(list) ((void *)((tlist *)(list))->lh_Head) X#define last(list) ((void *)((tlist *)(list))->lh_Tail) X#define empty(list) (((tlist *)(list))->lh_TailPred == (tnode *)(list)) X X#define succ(node) (void *)(((tnode *)(node))->ln_Succ) X#define pred(node) (void *)(((tnode *)(node))->ln_Pred) X X#define alloc_node(size) AllocMem((size), 0L) X X/* Free all elements of a homogeneous list */ Xvoid free_list(list *l, size_t size); X X#endif X SHAR_EOF echo "extracting lmkfile" sed 's/^X//' << \SHAR_EOF > lmkfile XFLAGS = -Hsmall.sym -csf -d3 -v -oo/ XINCS = object.h uio.h list.h grph.h coords.h graph.h X X.c.o: X lc $(FLAGS) $* X Xgraph: graph.d X blink from graph.d to graph nodebug X Xgraph.d: small.sym o/graph.o o/coords.o o/grph.o o/uio.o o/tracker.o o/list.o o X/pos.o o/label.o o/f_of_x.o o/x_y.o o/r_of_t.o o/function.o o/default.o o/r_t.o Xo/graphics.o o/gadgets.o X blink with lnk X Xsmall.sym: smallsym.c X lc -ph -osmall.sym smallsym.c X Xo/gadgets.o: gadgets/gadgets.c user/gadgets.h X Xo/graphics.o: graphics.c graphics.h X Xo/graph.o: graph.c $(INCS) X Xo/grph.o: grph.c $(INCS) graphics.h X Xo/uio.o: uio.c $(INCS) X Xo/coords.o: coords.c coords.h X Xo/list.o: list.c list.h X Xo/default.o: object/default.c object/default.h $(INCS) X Xo/pos.o: object/pos.c object/default.h $(INCS) X Xo/label.o: object/label.c object/default.h $(INCS) graphics.h X Xo/function.o: object/function.c object/function.h object/default.h $(INCS) X Xo/f_of_x.o: object/f_of_x.c object/function.h object/default.h $(INCS) X Xo/x_y.o: object/x_y.c object/function.h object/default.h $(INCS) X Xo/r_of_t.o: object/r_of_t.c object/function.h object/default.h $(INCS) X Xo/r_t.o: object/r_t.c object/function.h object/default.h $(INCS) X Xo/tracker.o: divers/tracker.c tracker.h X lc -v -O -m1t -oo/ divers/tracker X SHAR_EOF echo "extracting lmko" sed 's/^X//' << \SHAR_EOF > lmko XFLAGS = -Hsmall.sym -csf -O -v -ooO/ XINCS = object.h uio.h list.h grph.h coords.h graph.h X X.c.o: X lc $(FLAGS) $* X Xgraph: small.sym oO/graph.o oO/coords.o oO/grph.o oO/uio.o oO/list.o oO/pos.o o XO/label.o oO/f_of_x.o oO/x_y.o oO/r_of_t.o oO/function.o oO/default.o oO/r_t.o o XO/graphics.o oO/gadgets.o X blink with lnkO X Xsmall.sym: smallsym.c X lc -ph -osmall.sym smallsym.c X XoO/gadgets.o: gadgets/gadgets.c user/gadgets.h X XoO/graphics.o: graphics.c graphics.h X XoO/graph.o: graph.c $(INCS) X XoO/grph.o: grph.c $(INCS) graphics.h X XoO/uio.o: uio.c $(INCS) X XoO/coords.o: coords.c coords.h X XoO/list.o: list.c list.h X XoO/default.o: object/default.c object/default.h $(INCS) X XoO/pos.o: object/pos.c object/default.h $(INCS) X XoO/label.o: object/label.c object/default.h $(INCS) graphics.h X XoO/function.o: object/function.c object/function.h object/default.h $(INCS) X XoO/f_of_x.o: object/f_of_x.c object/function.h object/default.h $(INCS) X XoO/x_y.o: object/x_y.c object/function.h object/default.h $(INCS) X XoO/r_of_t.o: object/r_of_t.c object/function.h object/default.h $(INCS) X XoO/r_t.o: object/r_t.c object/function.h object/default.h $(INCS) X SHAR_EOF echo "extracting lnk" sed 's/^X//' << \SHAR_EOF > lnk XFROM LIB:c.o+o/graph.o+o/coords.o+o/uio.o+o/grph.o+o/tracker.o+o/list.o+o/gadge Xts.o+o/pos.o+o/label.o+o/f_of_x.o+o/x_y.o+o/r_of_t.o+o/function.o+o/default.o+o/ Xr_t.o+o/graphics.o XTO graph.d XLIB lib:eval.lib+lib:lcmieee.lib+lib:lcm.lib+LIB:lc.lib+LIB:amiga.lib XADDSYM XVERBOSE XBATCH Xsc X SHAR_EOF echo "extracting lnko" sed 's/^X//' << \SHAR_EOF > lnko Xfrom lib:c.o oO/graphics.o oO/coords.o oO/graph.o oO/grph.o oO/uio.o oO/gadgets X.o oO/label.o oO/function.o oO/f_of_x.o oO/x_y.o oO/r_t.o oO/r_of_t.o oO/list.o X oO/default.o oO/pos.o XTO graph XLIB lib:eval.lib+lib:lcmieee.lib+lib:lcm.lib+LIB:lc.lib+LIB:amiga.lib XNODEBUG XVERBOSE XBATCH Xsc SHAR_EOF echo "extracting make.shar" sed 's/^X//' << \SHAR_EOF > make.shar Xshar >graph.sh1 -p X README coords.c coords.h default.c default.h file.h functi Xon.c + X function.h f_of_x.c gadgets.c Xshar >graph.sh2 -p X gadgets.h graph.c graph.doc graph.h graphics.c graphics.h Xshar >graph.sh3 -p X grph.c grph.h label.c Xshar >graph.sh4 -p X list.c list.h lmkfile lmkO lnk lnkO mv2dir object.guidelin Xes + X object.h pos.c r_of_t.c r_t.c smallsym.c tracker.c tracker.h Xshar >graph.sh5 -p X uio.c uio.h x_y.c tracker.README make.shar SHAR_EOF echo "extracting mv2dir" sed 's/^X//' << \SHAR_EOF > mv2dir Xmakedir o Xmakedir oO Xmakedir gadgets Xmakedir user Xmakedir object Xmakedir divers Xrename gadgets.h user/gadgets.h Xrename gadgets.c gadgets/gadgets.c Xrename default.c object/default.c Xrename default.h object/default.h Xrename f_of_x.c object/f_of_x.c Xrename function.c object/function.c Xrename function.h object/function.h Xrename label.c object/label.c Xrename pos.c object/pos.c Xrename r_of_t.c object/r_of_t.c Xrename r_t.c object/r_t.c Xrename x_y.c object/x_y.c Xrename tracker.c divers X X SHAR_EOF echo "End of archive 5 (of 7)" # if you want to concatenate archives, remove anything after this line exit