pendulum68k/pendDialog.c

1 line
3.7 KiB
C
Raw Normal View History

2019-04-03 20:54:48 +00:00
#include "pendDialog.h" #include <errno.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "common.h" #define DLOG_PREFS 128 #define DLOG_ABOUT 129 #define PREFS_EDIT_START 3 #define PREFS_EDIT_END 7 enum { PREFS_THETA=0, PREFS_DTHETA, PREFS_MU, PREFS_LEN, PREFS_GRAV }; extern Boolean forceRedraw; static Boolean valid_input(double *n, int no) { if( *n == HUGE_VAL || *n == -HUGE_VAL || /*isnan(*n) ||*/ /* Cannot detect NANs */ (*n == 0.0 && errno == ERANGE)) { return false; } switch(no) { case PREFS_THETA: { *n = fmod(*n, 2*M_PI); if(*n > M_PI) *n -= 2*M_PI; } return true; case PREFS_LEN: case PREFS_GRAV: if(*n == 0.0) return false; return true; } return true; } static Boolean parse_pi(char *str) { return ((tolower(str[0]) == 'p') && (tolower(str[1]) == 'i') && (str[2] == '\0')); } static pascal Boolean aboutFilter(DialogPtr theDialog, EventRecord *theEvent, int *itemHit) { int windowCode; WindowPtr theWindow; if(theEvent->what != mouseDown) return false; windowCode = FindWindow(theEvent->where, &theWindow); if(windowCode != inContent || theWindow != theDialog) return false; return true; } void DialogAbout() { int itemHit; DialogPtr dlog = GetNewDialog(DLOG_ABOUT, NULL, (WindowPtr) -1L); ModalDialog(&aboutFilter, &itemHit); DisposDialog(dlog); forceRedraw = true; } void DialogPrefs(struct dialog_prefs_t *p) { union prefs_choose { struct dialog_prefs_t *rec; double *arr; /* Size 5 */ }; union prefs_choose args; double tmpargs[5]; StringPtr dblText; int itemHit, itemno; Boolean valid_settings = false; DialogPtr dlog; dblText = (StringPtr) NewPtr(sizeof(Str255)); if(!dblText) return; dlog = GetNewDialog(DLOG_PREFS, NULL, (WindowPtr) -1L); if(!dlog) goto err_dlog; args.rec = p; /* Convert p's fields to EditText fields */ for(itemno = PREFS_EDIT_START; itemno <= PREFS_EDIT_END; ++itemno) { int arrval = itemno - PREFS_EDIT_START; int itemType; ControlHandle itemHandle; Rect itemBox; PLEN(dblText) = sprintf((char *) PSTR(dblText), "%.9g", args.arr[arrval]); GetDItem(dlog, itemno, &itemType, &itemHandle, &itemBox); SetIText(itemHandle, dblText); } while(!valid_settings) { ModalDialog(NULL, &itemHit); if(itemHit == cancel) break; valid_settings = true; for(itemno = PREFS_EDIT_START; itemno <= PREFS_EDIT_END; ++itemno) { int arrval = itemno - PREFS_EDIT_START; int itemType; ControlHandle itemHandle; Rect itemBox; char *endpos; /* Convert EditText fields to p fields */ GetDItem(dlog, itemno, &itemType, &itemHandle, &itemBox); GetIText(itemHandle, dblText); /* If a field was left empty */ if(PLEN(dblText) == 0) { valid_settings = false; break; } /* Convert to Cstring */ if(PLEN(dblText) == 255) PSTR(dblText)[255] = '\0'; else PSTR(dblText)[PLEN(dblText)] = '\0'; /* Convert to double */ tmpargs[arrval] = strtod((char *) PSTR(dblText), &endpos); if(endpos == (char *) PSTR(dblText)) { /* Input: "pi" */ if(parse_pi(endpos)) { tmpargs[arrval] = M_PI; } else { valid_settings = false; break; } } else if(*endpos != '\0') { /* Input: "xx.xxpi" */ if(parse_pi(endpos)) { tmpargs[arrval] *= M_PI; } else { valid_settings = false; break; } } /* Modifies / Verifies input */ if(!valid_input(&tmpargs[arrval], arrval)) { valid_settings = false; break; } } /* Error condition */ if(!valid_settings) { SelIText(dlog, itemno, 0, 32767); SysBeep(0); } } if(itemHit == ok) memcpy(p, tmpargs, sizeof(tmpargs)); DisposDialog(dlog); err_dlog: DisposPtr(dblText); forceRedraw = true; }