Topograph release 1.1
This commit is contained in:
+344
@@ -0,0 +1,344 @@
|
||||
/* File CP.c */
|
||||
/* This module contains the instance data and methods for the Control Panel. */
|
||||
|
||||
/****************************************************************
|
||||
Topograph - A function browser
|
||||
Copyright (C) 1996 Marc Culler
|
||||
|
||||
culler@math.uic.edu
|
||||
|
||||
Department of Mathematics (M/C 249)
|
||||
University of Illinois at Chicago
|
||||
851 S. Morgan St.
|
||||
Chicago, IL 60607-7045
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
******************************************************************/
|
||||
|
||||
#include "Topograph.h"
|
||||
#include "graph.h"
|
||||
|
||||
/* This data structure is passed as a message to the graph process. See Topograph.h */
|
||||
|
||||
struct CPMessage CPmsg = { {{NULL,NULL,NT_MESSAGE,0,"CPMessage"}, /*Node */
|
||||
NULL, /*Reply*/
|
||||
sizeof(struct CPMessage)}, /*Size */
|
||||
0, /*Command */
|
||||
-1.0, 1.0, -.625, .625, -1.0, 1.0, 1.0, .625, TRUE, NULL, YES, NULL /*Data */
|
||||
};
|
||||
|
||||
/* Control panel methods. */
|
||||
void CP_draw(UWORD code);
|
||||
void CP_stop(UWORD code);
|
||||
void CP_rescale(UWORD code);
|
||||
void CP_zoom(double factor);
|
||||
void CP_newZMin(UWORD code);
|
||||
void CP_newZMax(UWORD code);
|
||||
void CP_newXMin(UWORD code);
|
||||
void CP_newXMax(UWORD code);
|
||||
void CP_newYMin(UWORD code);
|
||||
void CP_newYMax(UWORD code);
|
||||
void CP_newAspect(UWORD code);
|
||||
void CP_setAspect(UWORD code);
|
||||
void CP_computeAspect(void);
|
||||
void CP_adjustX(void);
|
||||
void CP_adjustY(void);
|
||||
void CP_displayDomain(void);
|
||||
void CP_displayRange(void);
|
||||
void CP_displayExtrema(struct graph *G);
|
||||
void CP_setTitle(char *string);
|
||||
void CP_disableRange(void);
|
||||
void CP_enableRange(void);
|
||||
void CP_buttons(ULONG flags);
|
||||
void CP_menusOff(void);
|
||||
void CP_menusOn(void);
|
||||
void CP_userMessage(char *title, char *message);
|
||||
|
||||
/* Defined in UI.c */
|
||||
extern struct Gadget *CPGadgets[];
|
||||
extern struct Window *CPWindow;
|
||||
extern char titleString[];
|
||||
extern void stackScreens(void);
|
||||
|
||||
/* Defined in ParseIO.c */
|
||||
extern void closeIOConsole(void);
|
||||
|
||||
/* Defined in Topograph.c */
|
||||
extern void graphMessage(int);
|
||||
|
||||
void CP_draw(UWORD code){
|
||||
closeIOConsole();
|
||||
graphMessage(DRAW_CMD);
|
||||
}
|
||||
|
||||
void CP_stop(UWORD code){
|
||||
|
||||
graphMessage(STOP_CMD);
|
||||
CP_buttons(DRAW_BUTTON);
|
||||
}
|
||||
|
||||
void CP_rescale(UWORD code){
|
||||
CP_disableRange();
|
||||
graphMessage(RESCALE_CMD);
|
||||
CP_displayRange();
|
||||
CP_enableRange();
|
||||
}
|
||||
|
||||
void CP_zoom(double factor){
|
||||
double middle, halfwidth;
|
||||
|
||||
graphMessage(RTNDOMAIN_CMD);
|
||||
middle = (CPmsg.xMax + CPmsg.xMin)/2;
|
||||
halfwidth = (CPmsg.xMax - CPmsg.xMin)/2;
|
||||
CPmsg.xMin = middle - factor*halfwidth;
|
||||
CPmsg.xMax = middle + factor*halfwidth;
|
||||
|
||||
middle = (CPmsg.yMax + CPmsg.yMin)/2;
|
||||
halfwidth = (CPmsg.yMax - CPmsg.yMin)/2;
|
||||
CPmsg.yMin = middle - factor*halfwidth;
|
||||
CPmsg.yMax = middle + factor*halfwidth;
|
||||
|
||||
CP_displayDomain();
|
||||
CPmsg.computeNewValues = YES;
|
||||
graphMessage(DRAW_CMD);
|
||||
}
|
||||
|
||||
|
||||
void CP_newXMin(UWORD code){
|
||||
struct StringInfo *SI = (struct StringInfo *)(CPGadgets[XMIN]->SpecialInfo);
|
||||
|
||||
sscanf(SI->Buffer, "%le", &(CPmsg.xMin));
|
||||
if (CPmsg.aspectIsFixed == TRUE) CP_adjustY();
|
||||
else CP_computeAspect();
|
||||
CP_displayDomain();
|
||||
}
|
||||
|
||||
void CP_newXMax(UWORD code){
|
||||
struct StringInfo *SI = (struct StringInfo *)(CPGadgets[XMAX]->SpecialInfo);
|
||||
|
||||
sscanf(SI->Buffer, "%le", &(CPmsg.xMax));
|
||||
if (CPmsg.aspectIsFixed == TRUE) CP_adjustY();
|
||||
else CP_computeAspect();
|
||||
CP_displayDomain();
|
||||
}
|
||||
|
||||
void CP_adjustY(void){
|
||||
double yMid = (CPmsg.yMax + CPmsg.yMin)/2;
|
||||
double halfSpan = (CPmsg.aspect)*(CPmsg.screenAspect)*(CPmsg.xMax - CPmsg.xMin)/2;
|
||||
|
||||
CPmsg.yMax = yMid + halfSpan;
|
||||
CPmsg.yMin = yMid - halfSpan;
|
||||
}
|
||||
|
||||
void CP_newYMin(UWORD code){
|
||||
struct StringInfo *SI = (struct StringInfo *)(CPGadgets[YMIN]->SpecialInfo);
|
||||
|
||||
sscanf(SI->Buffer, "%le", &(CPmsg.yMin));
|
||||
if (CPmsg.aspectIsFixed == TRUE) CP_adjustX();
|
||||
else CP_computeAspect();
|
||||
CP_displayDomain();
|
||||
}
|
||||
|
||||
void CP_newYMax(UWORD code){
|
||||
struct StringInfo *SI = (struct StringInfo *)(CPGadgets[YMAX]->SpecialInfo);
|
||||
|
||||
sscanf(SI->Buffer, "%le", &(CPmsg.yMax));
|
||||
if (CPmsg.aspectIsFixed == TRUE) CP_adjustX();
|
||||
else CP_computeAspect();
|
||||
CP_displayDomain();
|
||||
}
|
||||
|
||||
void CP_adjustX(){
|
||||
double xMid = (CPmsg.xMax + CPmsg.xMin)/2;
|
||||
double halfSpan = (CPmsg.yMax - CPmsg.yMin)/((CPmsg.aspect)*(CPmsg.screenAspect)*2);
|
||||
|
||||
CPmsg.xMax = xMid + halfSpan;
|
||||
CPmsg.xMin = xMid - halfSpan;
|
||||
}
|
||||
|
||||
void CP_computeAspect(void){
|
||||
CPmsg.aspect = (CPmsg.yMax - CPmsg.yMin)/(CPmsg.screenAspect*(CPmsg.xMax - CPmsg.xMin));
|
||||
}
|
||||
|
||||
void CP_newZMin(UWORD code){
|
||||
char buffer[30];
|
||||
struct StringInfo *SI = (struct StringInfo *)(CPGadgets[ZBOTTOM]->SpecialInfo);
|
||||
|
||||
sscanf(SI->Buffer, "%le", &(CPmsg.zMin));
|
||||
sprintf(buffer, "%10.6f", CPmsg.zMin);
|
||||
GT_SetGadgetAttrs(CPGadgets[ZBOTTOM], CPWindow, NULL,
|
||||
GTST_String, buffer,
|
||||
TAG_END);
|
||||
}
|
||||
|
||||
void CP_newZMax(UWORD code){
|
||||
char buffer[30];
|
||||
struct StringInfo *SI = (struct StringInfo *)(CPGadgets[ZTOP]->SpecialInfo);
|
||||
|
||||
sscanf(SI->Buffer, "%le", &(CPmsg.zMax));
|
||||
sprintf(buffer, "%10.6f", CPmsg.zMax);
|
||||
GT_SetGadgetAttrs(CPGadgets[ZTOP], CPWindow, NULL,
|
||||
GTST_String, buffer,
|
||||
TAG_END);
|
||||
}
|
||||
|
||||
void CP_newAspect(UWORD code){
|
||||
if (code == 0) {
|
||||
CPmsg.aspectIsFixed = TRUE;
|
||||
OffGadget(CPGadgets[ASPECT],CPWindow,NULL);
|
||||
}
|
||||
else {
|
||||
CPmsg.aspectIsFixed = FALSE;
|
||||
OnGadget(CPGadgets[ASPECT],CPWindow,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void CP_setAspect(UWORD code){
|
||||
char buffer[30];
|
||||
struct StringInfo *SI = (struct StringInfo *)(CPGadgets[ASPECT]->SpecialInfo);
|
||||
|
||||
sscanf(SI->Buffer, "%le", &(CPmsg.aspect));
|
||||
sprintf(buffer, "%10.6f", CPmsg.aspect);
|
||||
GT_SetGadgetAttrs(CPGadgets[ASPECT], CPWindow, NULL,
|
||||
GTST_String, buffer,
|
||||
TAG_END);
|
||||
CP_adjustY();
|
||||
CP_displayDomain();
|
||||
}
|
||||
|
||||
/* Update the domain info and the aspect ratio. */
|
||||
|
||||
void CP_displayDomain(void){
|
||||
char buffer[30];
|
||||
|
||||
sprintf(buffer, "%-10.6f", CPmsg.xMin);
|
||||
GT_SetGadgetAttrs(CPGadgets[XMIN], CPWindow,NULL,
|
||||
GTST_String, buffer,
|
||||
TAG_END);
|
||||
|
||||
sprintf(buffer, "%-10.6f", CPmsg.xMax);
|
||||
GT_SetGadgetAttrs(CPGadgets[XMAX], CPWindow,NULL,
|
||||
GTST_String, buffer,
|
||||
TAG_END);
|
||||
|
||||
sprintf(buffer, "%-10.6f", CPmsg.yMin);
|
||||
GT_SetGadgetAttrs(CPGadgets[YMIN], CPWindow,NULL,
|
||||
GTST_String, buffer,
|
||||
TAG_END);
|
||||
|
||||
sprintf(buffer, "%-10.6f", CPmsg.yMax);
|
||||
GT_SetGadgetAttrs(CPGadgets[YMAX], CPWindow,NULL,
|
||||
GTST_String, buffer,
|
||||
TAG_END);
|
||||
|
||||
sprintf(buffer, "%-10.6f", CPmsg.aspect);
|
||||
GT_SetGadgetAttrs(CPGadgets[ASPECT], CPWindow, NULL,
|
||||
GTST_String, buffer,
|
||||
TAG_END);
|
||||
}
|
||||
|
||||
/* Update the range info. */
|
||||
|
||||
void CP_displayRange(void){
|
||||
char buffer[30];
|
||||
|
||||
sprintf(buffer, "%-10.6f", CPmsg.zMin);
|
||||
GT_SetGadgetAttrs(CPGadgets[ZBOTTOM], CPWindow,NULL,
|
||||
GTST_String, buffer,
|
||||
TAG_END);
|
||||
|
||||
sprintf(buffer, "%-10.6f", CPmsg.zMax);
|
||||
GT_SetGadgetAttrs(CPGadgets[ZTOP], CPWindow,NULL,
|
||||
GTST_String, buffer,
|
||||
TAG_END);
|
||||
}
|
||||
|
||||
void CP_displayExtrema(struct graph *G){
|
||||
char buffer[30];
|
||||
|
||||
if (G->extremaAreKnown){
|
||||
sprintf(buffer, "%-10.6f", G->minimum);
|
||||
GT_SetGadgetAttrs(CPGadgets[ZMIN], CPWindow, NULL,
|
||||
GTTX_Text, buffer,
|
||||
TAG_END);
|
||||
|
||||
sprintf(buffer, "%-10.6f", G->maximum);
|
||||
GT_SetGadgetAttrs(CPGadgets[ZMAX], CPWindow, NULL,
|
||||
GTTX_Text, buffer,
|
||||
TAG_END);
|
||||
}
|
||||
|
||||
else {
|
||||
buffer[0] = '\0';
|
||||
|
||||
GT_SetGadgetAttrs(CPGadgets[ZMIN], CPWindow, NULL,
|
||||
GTTX_Text, buffer,
|
||||
TAG_END);
|
||||
|
||||
GT_SetGadgetAttrs(CPGadgets[ZMAX], CPWindow, NULL,
|
||||
GTTX_Text, buffer,
|
||||
TAG_END);
|
||||
}
|
||||
}
|
||||
|
||||
void CP_setTitle(char *string){
|
||||
if (string == NULL) string = titleString;
|
||||
SetWindowTitles(CPWindow, string, NULL);
|
||||
}
|
||||
|
||||
void CP_menusOff(void){
|
||||
OffMenu(CPWindow, FULLMENUNUM(0,0,NOSUB));
|
||||
OffMenu(CPWindow, FULLMENUNUM(0,3,NOSUB));
|
||||
OffMenu(CPWindow, FULLMENUNUM(1,NOITEM,NOSUB));
|
||||
}
|
||||
|
||||
void CP_menusOn(void){
|
||||
OnMenu(CPWindow, FULLMENUNUM(0,0,NOSUB));
|
||||
OnMenu(CPWindow, FULLMENUNUM(0,3,NOSUB));
|
||||
OnMenu(CPWindow, FULLMENUNUM(1,NOITEM,NOSUB));
|
||||
}
|
||||
|
||||
void CP_disableRange(void){
|
||||
OffGadget(CPGadgets[ZBOTTOM],CPWindow,NULL);
|
||||
OffGadget(CPGadgets[ZTOP],CPWindow,NULL);
|
||||
}
|
||||
|
||||
void CP_enableRange(void){
|
||||
OnGadget(CPGadgets[ZBOTTOM],CPWindow,NULL);
|
||||
OnGadget(CPGadgets[ZTOP],CPWindow,NULL);
|
||||
}
|
||||
|
||||
void CP_buttons(ULONG flags){
|
||||
if (flags & DRAW_BUTTON)OnGadget(CPGadgets[DRAW], CPWindow, NULL);
|
||||
else OffGadget(CPGadgets[DRAW], CPWindow, NULL);
|
||||
if (flags & RESCALE_BUTTON)OnGadget(CPGadgets[RESCALE], CPWindow, NULL);
|
||||
else OffGadget(CPGadgets[RESCALE], CPWindow, NULL);
|
||||
if (flags & STOP_BUTTON)OnGadget(CPGadgets[STOP], CPWindow, NULL);
|
||||
else OffGadget(CPGadgets[STOP], CPWindow, NULL);
|
||||
}
|
||||
|
||||
void CP_userMessage(char *title, char *message){
|
||||
struct EasyStruct ES = {
|
||||
sizeof(struct EasyStruct),
|
||||
0,
|
||||
NULL,
|
||||
"%s",
|
||||
"Oh"};
|
||||
|
||||
ES.es_Title = title;
|
||||
EasyRequest(CPWindow,&ES,0,message);
|
||||
stackScreens();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user