home *** CD-ROM | disk | FTP | other *** search
- /*
- * GRAPH, Version 1.00 - 4 August 1989
- *
- * Copyright 1989, David Gay. All Rights Reserved.
- * This software is freely redistrubatable.
- */
-
- /* The default/non virtual methods for class function */
- #include <exec/types.h>
- #include <intuition/intuition.h>
- #include <graphics/text.h>
- #include <math.h>
- #include <string.h>
-
- #include "object.h"
- #include "object/default.h"
- #include "object/function.h"
- #include "file.h"
- #include "graph.h"
- #include "uio.h"
- #include "coords.h"
- #include "list.h"
- #include "grph.h"
- #include "user/eval.h"
- #include "user/gadgets.h"
- #include "tracker.h"
-
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
-
- /* Draw a function */
- void display_function(struct function *this)
- {
- int up;
- point *pt;
- struct RWindow *const rwin = this->o.g->io.rw;
- int pen = this->selected ? (this->colour == 3 ? 2 : 3) : this->colour;
-
- up = TRUE;
-
- SetAPen(rwin->rp, pen);
- SetDrMd(rwin->rp, JAM1);
-
- /* Scan points (note that all types of function points have point as base c
- lass) */
- for (pt = first(&this->pts); succ(pt); pt = succ(pt))
- {
- if (pt->state & EXISTS)
- {
- if (up) RMove(rwin, pt->x, pt->y);
- else RDraw(rwin, pt->x, pt->y);
- up = this->showdisc && (pt->state & DISC);
- }
- else
- up = TRUE;
- }
- }
-
- /* Select function, redraw in new colour */
- static void select_function(struct function *this)
- {
- this->selected = TRUE;
- if (this->o.ok && this->o.g->ok && this->o.g->io.rw && this->calc)
- display_function(this);
- }
-
- /* Deselect function */
- static struct Region *deselect_function(struct function *this)
- {
- this->selected = FALSE;
- if (this->o.ok && this->o.g->ok && this->o.g->io.rw && this->calc)
- display_function(this);
- return NULL; /* No refresh needed */
- }
-
- /* Did user press mouse on function ? */
- static int down_function(struct function *this)
- {
- int inside = FALSE;
-
- if (this->o.ok && this->calc)
- {
- struct graph *g = this->o.g;
- point *pt;
- long sx = ftol(g->io.rw->sx(g->io.rw, g->s.x));
- long sy = ftol(g->io.rw->sy(g->io.rw, g->s.y));
- long x0, y0, x1, y1;
- int up = TRUE;
-
- /* Check if mouse "near" drawn line */
- for (pt = first(&this->pts); succ(pt); pt = succ(pt))
- {
- if (pt->state & EXISTS)
- {
- x1 = ftol(g->io.rw->sx(g->io.rw, pt->x));
- y1 = ftol(g->io.rw->sy(g->io.rw, pt->y));
-
- if (!up) /* segment exists, calc distance to it */
- {
- /* A little vectorial algebra */
- long ab_x, ab_y, u_x, u_y, h, hd, dist_x, dist_y, dist;
-
- ab_x = sx - x0; ab_y = sy - y0;
- u_x = x1 - x0; u_y = y1 - y0;
- h = (ab_x * u_x + ab_y * u_y);
- hd = (u_x * u_x + u_y * u_y);
- if (hd != 0 && 0 <= h && h <= hd) /* intersection on segmen
- t */
- {
- dist_x = (hd * ab_x - h * u_x) / hd; dist_y = (hd * ab_
- y - h * u_y) / hd;
- dist = dist_x * dist_x + dist_y * dist_y;
- if (dist < (FDIST * FDIST))
- {
- /* We're near segment ! */
- inside = TRUE;
- break;
- }
- }
- /* Near point ? */
- else if ((x1 - sx) * (x1 - sx) + (y1 - sy) * (y1 - sy) <= F
- DIST * FDIST)
- {
- inside = TRUE;
- break;
- }
- }
-
- up = this->showdisc && (pt->state & DISC);
- x0 = x1; y0 = y1;
- }
- else
- up = TRUE;
-
- }
- }
- return inside;
- }
-
- /* Impossible ... */
- static void move_function(struct function *this)
- {
- }
-
- /* Nothing to do */
- static struct Region *up_function(struct function *this)
- {
- return NULL;
- }
-
- /* redraw function, calc if necessary */
- static void draw_function(struct function *this, int allow_mes)
- {
- if (!this->calc) this->calc = this->calcf(this, allow_mes);
- if (this->calc) display_function(this);
- }
-
- /* variable name changed. recalc necessary ? */
- static void var_change_function(struct function *this, char *name)
- {
- if (this->calc && FindName(&this->used, name))
- {
- free_list(&this->pts, this->sizept);
- this->calc = FALSE;
- }
- }
-
- /* Write function to file */
- static int save_function(struct function *this, FILE *f)
- {
- short tag = FUNCTION_TAG;
- short end = FUNCTION_END;
- short showdisc = this->showdisc; /* Can't write bitfields directly ... */
- short nicedisc = this->nicedisc;
-
- return WRITE(f, tag) &&
- this->save(this, f) && /* Easier than rewriting this for each fun
- ction */
- WRITE(f, this->o.name) &&
- WRITE(f, this->vname) &&
- WRITE(f, this->min) &&
- WRITE(f, this->max) &&
- WRITE(f, this->steps) &&
- WRITE(f, this->colour) &&
- WRITE(f, showdisc) &&
- WRITE(f, nicedisc) &&
- WRITE(f, end);
- }
-
- /* Read a function from a file */
- struct function *load_function(struct graph *g, FILE *f)
- {
- short tag;
- struct function *this;
-
- if (READ(f, tag)) /* Determine which type of function */
- switch (tag)
- {
- case F_OF_X_TAG:
- this = (struct function *)load_f_of_x(g, f);
- break;
- case X_Y_TAG:
- this = (struct function *)load_x_y(g, f);
- break;
- case R_OF_T_TAG:
- this = (struct function *)load_r_of_t(g, f);
- break;
- case R_T_TAG:
- this = (struct function *)load_r_t(g, f);
- break;
- default:
- message(g, "Not a graph file", (char *)NULL);
- }
- return this;
- }
-
- /* Read "standard" part of function from file */
- int load_rest(struct function *this, FILE *f)
- {
- short showdisc, nicedisc, end;
-
- if (READ(f, this->o.name) &&
- READ(f, this->vname) &&
- READ(f, this->min) &&
- READ(f, this->max) &&
- READ(f, this->steps) &&
- READ(f, this->colour) &&
- READ(f, showdisc) && /* Can't read bitfields directly */
- READ(f, nicedisc) &&
- READ(f, end) &&
- end == FUNCTION_END)
- {
- this->showdisc = showdisc;
- this->nicedisc = nicedisc;
- return TRUE;
- }
- return FALSE;
- }
-
- /* Nothing to do (don't care about resolution) */
- static int inform_function(struct function *this)
- {
- return TRUE;
- }
-
- /* idem */
- static void confirm_function(struct object *this, int ok)
- {
- }
-
- /* Standard function init */
- void init_function(struct function *this, struct graph *g, char *name)
- {
- const static struct function def_f =
- {
- {
- { NULL }, NULL, "", FALSE, 0, 0,
- /* Default methods */
- (void *)uncalled, (void *)select_function, (void *)deselect_functio
- n,
- (void *)down_function, (void *)move_function, (void *)up_function,
- (void *)uncalled, (void *)draw_function, (void *)ref_uncalled,
- (void *)uncalled, (void *)var_change_function, (void *)save_functio
- n,
- (void *)inform_function, (void *)confirm_function
- },
- (void *)uncalled, (void *)uncalled,
- "", NOVAL, NOVAL, INOVAL,
- 1, TRUE, TRUE, FALSE, FALSE
- };
-
- *this = def_f;
- this->o.g = g;
- strcpy(this->o.name, name);
- init_var_list(&this->used);
- }
-
- /* Create a new function (ask user which type he wants) */
- struct function *new_function(struct graph *g)
- {
- struct Requester *req;
- struct Memory *m;
- struct Gadget *gl = NULL, *fx, *xy, *rt, *r2;
- char name[FNAMELEN];
- int ret = FALSE;
- struct function *o = NULL;
-
- name[0] = '\0';
-
- if ((m = NewMemory()) &&
- (req = InitReq(50, 20, 230, 105, m)) &&
- SetReqBorder(req, 1, m) &&
- AddIntuiText(&req->ReqText, "Add Function", 67, 6, m) &&
- AddText(&gl, 0, "Name ", FALSE, name, FNAMELEN, TRUE, 0, RELVERIFY, 51,
- 20, 100, 10, TRUE, m) &&
- (fx = AddRadio(&gl, 0, "f(x)", TRUE, SELECTED, RELVERIFY, 28, 11, 40, 1
- 0, 10, m)) &&
- (rt = AddRadio(&gl, 0, "r(theta)", TRUE, 0, RELVERIFY, 26, 105, 40, 10,
- 10, m)) &&
- (xy = AddRadio(&gl, 0, "x(t),y(t)", TRUE, 0, RELVERIFY, 22, 11, 60, 10,
- 10, m)) &&
- (r2 = AddRadio(&gl, 0, "r(t),theta(t)", TRUE, 0, RELVERIFY, 14, 105, 60
- , 10, 10, m)) &&
- AddBox(&gl, TRUE, "Ok", 0, RELVERIFY | ENDGADGET, 25, 80, 65, 15, FALSE
- , m) &&
- AddBox(&gl, FALSE, "Cancel", 0, RELVERIFY | ENDGADGET, 140, 80, 65, 15,
- FALSE, m))
- {
- SetReqGadgets(req, gl);
- if (ret = DoRequest(req, g, std_ghandler))
- {
- strip(name);
- if (*name)
- {
- if (fx->Flags & SELECTED) o = (struct function *)new_f_of_x(g,
- name);
- else if (xy->Flags & SELECTED) o = (struct function *)new_x_y(g
- , name);
- else if (rt->Flags & SELECTED) o = (struct function *)new_r_of_
- t(g, name);
- else o = (struct function *)new_r_t(g, name);
- }
- else
- message(g, "Blank names not allowed", (char *)NULL);
- }
- }
- Free(m);
- return o;
- }
-
-