Files
2017-04-17 00:10:12 +02:00

345 lines
9.9 KiB
C

/* 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();
}