diff options
Diffstat (limited to 'app/bin/param.c')
-rw-r--r-- | app/bin/param.c | 2699 |
1 files changed, 2699 insertions, 0 deletions
diff --git a/app/bin/param.c b/app/bin/param.c new file mode 100644 index 0000000..c58a4fa --- /dev/null +++ b/app/bin/param.c @@ -0,0 +1,2699 @@ +/** \file param.c + * Handle all the dialog box creation stuff. + */ + +/* XTrkCad - Model Railroad CAD + * Copyright (C) 2005 Dave Bullis + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <stdlib.h> +#include <stdio.h> +#ifndef WINDOWS +#include <unistd.h> +#include <dirent.h> +#endif +#ifdef HAVE_MALLOC_H +#include <malloc.h> +#endif +#include <math.h> +#include <ctype.h> +#include <string.h> +#include <time.h> +#ifdef WINDOWS +#include <io.h> +#include <windows.h> +#define R_OK (02) +#define access _access +#else +#include <sys/stat.h> +#include <errno.h> +#endif +#include <stdarg.h> +#include <locale.h> +#include <wlib.h> +#include "track.h" +#include "common.h" +#include "utility.h" +#include "misc.h" +#include "compound.h" +#include "i18n.h" + + +/* Bogus reg vars */ +EXPORT int paramLevel = 1; +EXPORT int paramLen; +EXPORT unsigned long paramKey; +EXPORT char paramId[100]; +EXPORT BOOL_T paramTogglePlaybackHilite; + +EXPORT char *PREFSECT = "DialogItem"; + +static int paramCheckErrorCount = 0; +static BOOL_T paramCheckShowErrors = FALSE; + +static int log_hotspot; +static int hotspotOffsetX = 5; +static int hotspotOffsetY = 19; + +static int log_paramLayout; + + +#ifdef LATER +/***************************************************************************** + * + * Colors + * + */ + +typedef struct { + long rgb; + char * name; + wDrawColor color; + } colorTab_t[]; + +static colorTab_t colorTab = { + { wRGB( 0, 0, 0), N_("Black") }, + + { wRGB( 0, 0,128), N_("Dark Blue") }, + { wRGB( 70,130,180), N_("Steel Blue") }, + { wRGB( 65,105,225), N_("Royal Blue") }, + { wRGB( 0, 0,255), N_("Blue") }, + { wRGB( 0,191,255), N_("Deep Sky Blue") }, + { wRGB(125,206,250), N_("Light Sky Blue") }, + { wRGB(176,224,230), N_("Powder Blue") }, + + { wRGB( 0,128,128), N_("Dark Aqua") }, + { wRGB(127,255,212), N_("Aquamarine") }, + { wRGB( 0,255,255), N_("Aqua") }, + + { wRGB( 0,128, 0), N_("Dark Green") }, + { wRGB( 34,139, 34), N_("Forest Green") }, + { wRGB( 50,205, 50), N_("Lime Green") }, + { wRGB( 0,255, 0), N_("Green") }, + { wRGB(124,252, 0), N_("Lawn Green") }, + { wRGB(152,251,152), N_("Pale Green") }, + + { wRGB(128,128, 0), N_("Dark Yellow") }, + { wRGB(255,127, 80), N_("Coral") }, + { wRGB(255,165, 0), N_("Orange") }, + { wRGB(255,215, 0), N_("Gold") }, + { wRGB(255,255, 0), N_("Yellow") }, + + { wRGB(139, 69, 19), N_("Saddle Brown") }, + { wRGB(165, 42, 42), N_("Brown") }, + { wRGB(210,105, 30), N_("Chocolate") }, + { wRGB(188,143,143), N_("Rosy Brown") }, + { wRGB(210,180,140), N_("Tan") }, + { wRGB(245,245,220), N_("Beige") }, + + + { wRGB(128, 0, 0), N_("Dark Red") }, + { wRGB(255, 99, 71), N_("Tomato") }, + { wRGB(255, 0, 0), N_("Red") }, + { wRGB(255,105,180), N_("Hot Pink") }, + { wRGB(255,192,203), N_("Pink") }, + + { wRGB(128, 0,128), N_("Dark Purple") }, + { wRGB(176, 48, 96), N_("Maroon") }, + { wRGB(160, 32,240), N_("Purple2") }, + { wRGB(255, 0,255), N_("Purple") }, + { wRGB(238,130,238), N_("Violet") }, + + { wRGB( 64, 64, 64), N_("Dark Gray") }, + { wRGB(128,128,128), N_("Gray") }, + { wRGB(192,192,192), N_("Light Gray") } }; +static wIcon_p colorTabBitMaps[ sizeof colorTab/sizeof colorTab[0] ]; +#include "bitmaps/square10.xbm" + +static BOOL_T colorTabInitted = FALSE; + +static void InitColorTab( void ) +{ + wIndex_t inx; + for ( inx=0; inx<COUNT(colorTab); inx++ ) + colorTab[inx].color = wDrawFindColor( colorTab[inx].rgb ); + colorTabInitted = TRUE; +} + + +static wIndex_t ColorTabLookup( wDrawColor color ) +{ + wIndex_t inx; + if (!colorTabInitted) + InitColorTab(); + for (inx = 0; inx < sizeof colorTab/sizeof colorTab[0]; inx++ ) + if (colorTab[inx].color == color) + return inx; + return 0; +} +#endif + +/***************************************************************************** + * + * + * + */ + +static char * getNumberError; +static char decodeErrorStr[STR_SHORT_SIZE]; + +static int GetDigitStr( char ** cpp, long * numP, int * lenP ) +{ + char *cp=*cpp, *cq; + int len; + *numP = 0; + if ( cp == NULL ) { + getNumberError = N_("Unexpected End Of String"); + return FALSE; + } + while ( isspace(*cp) ) cp++; + *numP = strtol( cp, &cq, 10 ); + if ( cp==cq ) { + *cpp = cp; + getNumberError = N_("Expected digit"); + return FALSE; + } + len = cq-cp; + if ( lenP ) + *lenP = len; + if ( len > 9 ) { + getNumberError = N_("Overflow"); + return FALSE; + } + while ( isspace(*cq) ) cq++; + *cpp = cq; + return TRUE; +} + +static int GetNumberStr( char ** cpp, FLOAT_T * numP, BOOL_T * hasFract ) +{ + long n0=0, f1, f2; + int l1; + char * cp = NULL; + struct lconv *lc; + + while ( isspace(**cpp) ) (*cpp)++; + + /* Find out the decimal separator of the current locale */ + lc = localeconv(); + + if ( **cpp != lc->decimal_point[0] + && !GetDigitStr( cpp, &n0, NULL ) ) + return FALSE; + if ( **cpp == lc->decimal_point[0] ) { + (*cpp)++; + if ( !isdigit(**cpp) ) { + *hasFract = FALSE; + *numP = (FLOAT_T)n0; + return TRUE; + } + if ( !GetDigitStr( cpp, &f1, &l1 ) ) return FALSE; + for ( f2=1; l1>0; l1-- ) f2 *= 10; + *numP = ((FLOAT_T)n0)+((FLOAT_T)f1)/((FLOAT_T)f2); + *hasFract = TRUE; + return TRUE; /* 999.999 */ + } + if ( isdigit( **cpp ) ) { + cp = *cpp; + if ( !GetDigitStr( cpp, &f1, NULL ) ) return FALSE; + } else { + f1 = n0; + n0 = 0; + } + if ( **cpp == '/' ) { + (*cpp)++; + if ( !GetDigitStr( cpp, &f2, &l1 ) ) return FALSE; + if ( f2 == 0 ) { + (*cpp) -= l1; + getNumberError = N_("Divide by 0"); + return FALSE; /* div by 0 */ + } + *numP = ((FLOAT_T)n0)+((FLOAT_T)f1)/((FLOAT_T)f2); + *hasFract = TRUE; + } else { + if ( cp != NULL ) { + *cpp = cp; + getNumberError = N_("Expected /"); + return FALSE; /* 999 999 ?? */ + } else { + *hasFract = FALSE; + *numP = f1; + } + } + return TRUE; +} +extern wIndex_t distanceFormatInx; // distanceFormatInx + +static BOOL_T GetDistance( char ** cpp, FLOAT_T * distP ) +{ + FLOAT_T n1, n2; + BOOL_T neg = FALSE; + BOOL_T hasFract; + BOOL_T expectInch = FALSE; + long distanceFormat; + + while ( isspace(**cpp) ) (*cpp)++; + if ( (*cpp)[0] == '\0' ) { + *distP = 0.0; + return TRUE; + } + if ( (*cpp)[0] == '-' ) { + neg = TRUE; + (*cpp)++; + } + if ( !GetNumberStr( cpp, &n1, &hasFract ) ) return FALSE; + + distanceFormat = GetDistanceFormat(); + + + if ( (*cpp)[0] == '\0' ) { /* EOL */ + if ( units==UNITS_METRIC ) + { + n1 = n1/2.54; + if ((distanceFormat & DISTFMT_FMT) == DISTFMT_FMT_MM) + n1 /= 10; + if ((distanceFormat & DISTFMT_FMT) == DISTFMT_FMT_M) + n1 *= 100; + } else { + if (((distanceFormat & DISTFMT_FMT) == DISTFMT_FMT_SHRT) || ((distanceFormat & DISTFMT_FMT) == DISTFMT_FMT_LONG)) + n1 *= 12; + } + if ( neg ) + n1 = -n1; + *distP = n1; + return TRUE; + } + if ( (*cpp)[0] == '\'' ) { + n1 *= 12.0; + (*cpp) += 1; + expectInch = !hasFract; + } else if ( tolower((*cpp)[0]) == 'f' && tolower((*cpp)[1]) == 't' ) { + n1 *= 12.0; + (*cpp) += 2; + expectInch = !hasFract; + } else if ( tolower((*cpp)[0]) == 'c' && tolower((*cpp)[1]) == 'm' ) { + n1 /= 2.54; + (*cpp) += 2; + } else if ( tolower((*cpp)[0]) == 'm' && tolower((*cpp)[1]) == 'm' ) { + n1 /= 25.4; + (*cpp) += 2; + } else if ( tolower((*cpp)[0]) == 'm' ) { + n1 *= 100.0/2.54; + (*cpp) += 1; + } else if ( (*cpp)[0] == '"' ) { + (*cpp) += 1; + } else if ( tolower((*cpp)[0]) == 'i' && tolower((*cpp)[1]) == 'n' ) { + (*cpp) += 2; + } else { + getNumberError = N_("Invalid Units Indicator"); + return FALSE; + } + while ( isspace(**cpp) ) (*cpp)++; + if ( expectInch && isdigit( **cpp ) ) { + if ( !GetNumberStr( cpp, &n2, &hasFract ) ) return FALSE; + n1 += n2; + if ( (*cpp)[0] == '"' ) + (*cpp) += 1; + else if ( tolower((*cpp)[0]) == 'i' && tolower((*cpp)[1]) == 'n' ) + (*cpp) += 2; + while ( isspace(**cpp) ) (*cpp)++; + } + if ( **cpp ) { + getNumberError = N_("Expected End Of String"); + return FALSE; + } + if ( neg ) + n1 = -n1; + *distP = n1; + return TRUE; +} + + +EXPORT FLOAT_T DecodeFloat( + wString_p strCtrl, + BOOL_T * validP ) +{ + FLOAT_T valF; + const char *cp0, *cp1; + char *cp2; + cp0 = cp1 = wStringGetValue( strCtrl ); + while (isspace(*cp1)) cp1++; + if ( *cp1 ) { + valF = strtod( cp1, &cp2 ); + if ( *cp2 != 0 ) { + /*wStringSetHilight( strCtrl, cp2-cp0, -1 );*/ + sprintf( decodeErrorStr, _("Invalid Number") ); + *validP = FALSE; + return 0.0; + } + *validP = TRUE; + return valF; + } else { + *validP = TRUE; + return 0.0; + } +} + + +EXPORT FLOAT_T DecodeDistance( + wString_p strCtrl, + BOOL_T * validP ) +{ + FLOAT_T valF; + char *cp0, *cp1, *cpN, c1; + + cp0 = cp1 = cpN = CAST_AWAY_CONST wStringGetValue( strCtrl ); + cpN += strlen(cpN)-1; + while (cpN > cp1 && isspace(*cpN) ) cpN--; + c1 = *cpN; + switch ( c1 ) { + case '=': + case 's': + case 'S': + case 'p': + case 'P': + *cpN = '\0'; + break; + default: + cpN = NULL; + } + *validP = ( GetDistance( &cp1, &valF ) ); + if ( cpN ) + *cpN = c1; + if ( *validP ) { +/*fprintf( stderr, "gd=%0.6f\n", valF );*/ + if ( c1 == 's' || c1 == 'S' ) + valF *= curScaleRatio; + else if ( c1 == 'p' || c1 == 'P' ) + valF /= curScaleRatio; + if ( cpN ) + wStringSetValue( strCtrl, FormatDistance( valF ) ); + } else { +/*fprintf( stderr, "Gd( @%s ) error=%s\n", cp1, getNumberError );*/ + sprintf( decodeErrorStr, "%s @ %s", _(getNumberError), *cp1?cp1:_("End Of String") ); + /*wStringSetHilight( strCtrl, cp1-cp0, -1 ); */ + valF = 0.0; + } + return valF; +} + + +#define N_STRING (10) +static char formatStrings[N_STRING][40]; +static int formatStringInx; + +EXPORT char * FormatLong( + long valL ) +{ + if ( ++formatStringInx >= N_STRING ) + formatStringInx = 0; + sprintf( formatStrings[formatStringInx], "%ld", valL ); + return formatStrings[formatStringInx]; +} + + +EXPORT char * FormatFloat( + FLOAT_T valF ) +{ + if ( ++formatStringInx >= N_STRING ) + formatStringInx = 0; + sprintf( formatStrings[formatStringInx], "%0.3f", valF ); + return formatStrings[formatStringInx]; +} + + +static void FormatFraction( + char ** cpp, + BOOL_T printZero, + int digits, + BOOL_T rational, + FLOAT_T valF, + char * unitFmt ) +{ + char * cp = *cpp; + long integ; + long f1, f2; + char * space = ""; + + if ( !rational ) { + sprintf( cp, "%0.*f", digits, valF ); + cp += strlen(cp); + } else { + integ = (long)floor(valF); + valF -= (FLOAT_T)integ; + for ( f2=1; digits>0; digits--,f2*=2 ); + f1 = (long)floor( (valF*(FLOAT_T)f2) + 0.5 ); + if ( f1 >= f2 ) { + f1 -= f2; + integ++; + } + if ( integ != 0 || !printZero ) { + sprintf( cp, "%ld", integ ); + cp += strlen(cp); + printZero = FALSE; + space = " "; + } + if ( f2 > 1 && f1 != 0 ) { + while ( (f1&1) == 0 ) { f1 /= 2; f2 /= 2; } + sprintf( cp, "%s%ld/%ld", space, f1, f2 ); + cp += strlen(cp); + } else if ( printZero ) { + *cp++ = '0'; + *cp = '\0'; + } + } + if ( cp != *cpp ) { + strcpy( cp, unitFmt ); + cp += strlen(cp); + *cpp = cp; + } +} + + +EXPORT char * FormatDistanceEx( + FLOAT_T valF, + long distanceFormat ) +{ + char * cp; + int digits; + long feet; + char * metricInd; + + if ( ++formatStringInx >= N_STRING ) + formatStringInx = 0; + cp = formatStrings[formatStringInx]; + digits = (int)(distanceFormat&DISTFMT_DECS); + valF = PutDim(valF); + if ( valF < 0 ) { + *cp++ = '-'; + valF = -valF; + } + if ( (distanceFormat&DISTFMT_FMT) == DISTFMT_FMT_NONE ) { + FormatFraction( &cp, FALSE, digits, (distanceFormat&DISTFMT_FRACT) == DISTFMT_FRACT_FRC, valF, "" ); + return formatStrings[formatStringInx]; + } else if ( units == UNITS_ENGLISH ) { + feet = (long)(floor)(valF/12.0); + valF -= feet*12.0; + if ( feet != 0 ) { + sprintf( cp, "%ld%s", feet, (distanceFormat&DISTFMT_FMT)==DISTFMT_FMT_SHRT?"' ":"ft " ); + cp += strlen(cp); + } + if ( feet==0 || valF != 0 ) { + FormatFraction( &cp, feet==0, digits, (distanceFormat&DISTFMT_FRACT) == DISTFMT_FRACT_FRC, valF, + (distanceFormat&DISTFMT_FMT)==DISTFMT_FMT_SHRT?"\"":"in" ); + } + } else { + if ( (distanceFormat&DISTFMT_FMT)==DISTFMT_FMT_M ) { + valF = valF/100.0; + metricInd = "m"; + } else if ( (distanceFormat&DISTFMT_FMT)==DISTFMT_FMT_MM ) { + valF = valF*10.0; + metricInd = "mm"; + } else { + metricInd = "cm"; + } + FormatFraction( &cp, FALSE, digits, (distanceFormat&DISTFMT_FRACT) == DISTFMT_FRACT_FRC, valF, metricInd ); + } + return formatStrings[formatStringInx]; +} + + +EXPORT char * FormatDistance( + FLOAT_T valF ) +{ + return FormatDistanceEx( valF, GetDistanceFormat() ); +} + +EXPORT char * FormatSmallDistance( + FLOAT_T valF ) +{ + long format = GetDistanceFormat(); + format &= ~(DISTFMT_FRACT_FRC|DISTFMT_DECS); + format |= 3; + return FormatDistanceEx( valF, format ); +} + +/***************************************************************************** + * + * + * + */ + +EXPORT void ParamControlActive( + paramGroup_p pg, + int inx, + BOOL_T active ) +{ + paramData_p p = &pg->paramPtr[inx]; + if ( p->control ) + wControlActive( p->control, active ); +} + + +EXPORT void ParamLoadMessage( + paramGroup_p pg, + int inx, + char * message ) +{ + paramData_p p = &pg->paramPtr[inx]; + if ( p->control ) { + if ( p->type == PD_MESSAGE ) + wMessageSetValue( (wMessage_p)p->control, message ); + else if ( p->type == PD_STRING ) + wStringSetValue( (wString_p)p->control, message ); + else + AbortProg( "paramLoadMessage: not a PD_MESSAGE or PD_STRING" ); + } +} + + +EXPORT void ParamLoadControl( + paramGroup_p pg, + int inx ) +{ + paramData_p p = &pg->paramPtr[inx]; + FLOAT_T tmpR; + char * valS; + + if ( (p->option&PDO_DLGIGNORE) != 0 ) + return; + if (p->control == NULL || p->valueP == NULL) + return; + switch ( p->type ) { + case PD_LONG: + wStringSetValue( (wString_p)p->control, FormatLong( *(long*)p->valueP ) ); + p->oldD.l = *(long*)p->valueP; + break; + case PD_RADIO: + wRadioSetValue( (wChoice_p)p->control, *(long*)p->valueP ); + p->oldD.l = *(long*)p->valueP; + break; + case PD_TOGGLE: + wToggleSetValue( (wChoice_p)p->control, *(long*)p->valueP ); + p->oldD.l = *(long*)p->valueP; + break; + case PD_LIST: + case PD_DROPLIST: + case PD_COMBOLIST: + wListSetIndex( (wList_p)p->control, *(wIndex_t*)p->valueP ); + p->oldD.l = *(wIndex_t*)p->valueP; + break; + case PD_COLORLIST: +#ifdef LATER + inx = ColorTabLookup( *(wDrawColor*)p->valueP ); + wListSetIndex( (wList_p)p->control, inx ); +#endif + wColorSelectButtonSetColor( (wButton_p)p->control, *(wDrawColor*)p->valueP ); + p->oldD.dc = *(wDrawColor*)p->valueP; + break; + case PD_FLOAT: + tmpR = *(FLOAT_T*)p->valueP; + if (p->option&PDO_DIM) { + if (p->option&PDO_SMALLDIM) + valS = FormatSmallDistance( tmpR ); + else + valS = FormatDistance( tmpR ); + } else { + if (p->option&PDO_ANGLE) + tmpR = NormalizeAngle( (angleSystem==ANGLE_POLAR)?tmpR:-tmpR ); + valS = FormatFloat( tmpR ); + } + wStringSetValue( (wString_p)p->control, valS ); + p->oldD.f = tmpR; + break; + case PD_STRING: + wStringSetValue( (wString_p)p->control, (char*)p->valueP ); + if (p->oldD.s) + MyFree( p->oldD.s ); + p->oldD.s = MyStrdup( (char*)p->valueP ); + break; + case PD_MESSAGE: + wMessageSetValue( (wMessage_p)p->control, _((char*)p->valueP) ); + break; + case PD_TEXT: + wTextClear( (wText_p)p->control ); + wTextAppend( (wText_p)p->control, (char*)p->valueP ); + break; + case PD_BUTTON: + case PD_DRAW: + case PD_MENU: + case PD_MENUITEM: + break; + } +} + + +/** Load all the controls in a parameter group. +* \param IN pointer to parameter group to be loaded +*/ +EXPORT void ParamLoadControls( + paramGroup_p pg ) +{ + int inx; + for ( inx=0; inx<pg->paramCnt; inx++ ) + ParamLoadControl( pg, inx ); +} + + +EXPORT long ParamUpdate( + paramGroup_p pg ) +{ + long longV; + FLOAT_T floatV; + const char * stringV; + wDrawColor dc; + long change = 0; + int inx; + paramData_p p; + BOOL_T valid; + + for ( p=pg->paramPtr,inx=0; p<&pg->paramPtr[pg->paramCnt]; p++,inx++ ) { + if ( (p->option&PDO_DLGIGNORE) != 0 ) + continue; + if ( p->control == NULL ) + continue; + switch ( p->type ) { + case PD_LONG: + stringV = wStringGetValue( (wString_p)p->control ); + longV = atol( stringV ); + if (longV != p->oldD.l) { + p->oldD.l = longV; + if ( /*(p->option&PDO_NOUPDUPD)==0 &&*/ p->valueP) + *(long*)p->valueP = longV; + if ( (p->option&PDO_NOUPDACT)==0 && pg->changeProc) + pg->changeProc( pg, inx, &longV ); + change |= (1L<<inx); + } + break; + case PD_RADIO: + longV = wRadioGetValue( (wChoice_p)p->control ); + if (longV != p->oldD.l) { + p->oldD.l = longV; + if ( /*(p->option&PDO_NOUPDUPD)==0 &&*/ p->valueP) + *(long*)p->valueP = longV; + if ( (p->option&PDO_NOUPDACT)==0 && pg->changeProc) + pg->changeProc( pg, inx, &longV ); + change |= (1L<<inx); + } + break; + case PD_TOGGLE: + longV = wToggleGetValue( (wChoice_p)p->control ); + if (longV != p->oldD.l) { + p->oldD.l = longV; + if ( /*(p->option&PDO_NOUPDUPD)==0 &&*/ p->valueP) + *(long*)p->valueP = longV; + if ( (p->option&PDO_NOUPDACT)==0 && pg->changeProc) + pg->changeProc( pg, inx, &longV ); + change |= (1L<<inx); + } + break; + case PD_LIST: + case PD_DROPLIST: + case PD_COMBOLIST: + longV = wListGetIndex( (wList_p)p->control ); + if (longV != p->oldD.l) { + p->oldD.l = longV; + if ( /*(p->option&PDO_NOUPDUPD)==0 &&*/ p->valueP) + *(wIndex_t*)p->valueP = (wIndex_t)longV; + if ( (p->option&PDO_NOUPDACT)==0 && pg->changeProc) + pg->changeProc( pg, inx, &longV ); + change |= (1L<<inx); + } + break; + case PD_COLORLIST: + dc = wColorSelectButtonGetColor( (wButton_p)p->control ); +#ifdef LATER + inx = wListGetIndex( (wList_p)p->control ); + dc = colorTab[inx].color; +#endif + if (dc != p->oldD.dc) { + p->oldD.dc = dc; + if ( /*(p->option&PDO_NOUPDUPD)==0 &&*/ p->valueP) + *(wDrawColor*)p->valueP = dc; + if ( (p->option&PDO_NOUPDACT)==0 && pg->changeProc) { + pg->changeProc( pg, inx, &longV ); /* COLORNOP */ + } + change |= (1L<<inx); + } + break; + case PD_FLOAT: + if (p->option & PDO_DIM) { + floatV = DecodeDistance( (wString_p)p->control, &valid ); + } else { + floatV = DecodeFloat( (wString_p)p->control, &valid ); + if (valid && (p->option & PDO_ANGLE) ) + floatV = NormalizeAngle( (angleSystem==ANGLE_POLAR)?floatV:-floatV ); + } + if ( !valid ) + break; + if (floatV != p->oldD.f) { + p->oldD.f = floatV; + if ( /*(p->option&PDO_NOUPDUPD)==0 &&*/ p->valueP) + *(FLOAT_T*)p->valueP = floatV; + if ( (p->option&PDO_NOUPDACT)==0 && pg->changeProc) + pg->changeProc( pg, inx, &floatV ); + change |= (1L<<inx); + } + break; + case PD_STRING: + stringV = wStringGetValue( (wString_p)p->control ); + if ( strcmp( stringV, p->oldD.s ) != 0 ) { + if (p->oldD.s) + MyFree( p->oldD.s ); + p->oldD.s = MyStrdup( stringV ); + if ( /*(p->option&PDO_NOUPDUPD)==0 &&*/ p->valueP) + strcpy( (char*)p->valueP, stringV ); + if ( (p->option&PDO_NOUPDACT)==0 && pg->changeProc) + pg->changeProc( pg, inx, CAST_AWAY_CONST stringV ); + change |= (1L<<inx); + } + break; + case PD_MESSAGE: + case PD_BUTTON: + case PD_DRAW: + case PD_TEXT: + case PD_MENU: + case PD_MENUITEM: + break; + } + } +#ifdef PGPROC + if (pg->proc) + pg->proc( PGACT_UPDATE, change ); +#endif + return change; +} + + +EXPORT void ParamLoadData( + paramGroup_p pg ) +{ + FLOAT_T floatV; + const char * stringV; + paramData_p p; + BOOL_T valid; + + for ( p=pg->paramPtr; p<&pg->paramPtr[pg->paramCnt]; p++ ) { + if ( (p->option&PDO_DLGIGNORE) != 0 ) + continue; + if ( p->control == NULL || p->valueP == NULL) + continue; + switch ( p->type ) { + case PD_LONG: + stringV = wStringGetValue( (wString_p)p->control ); + *(long*)p->valueP = atol( stringV ); + break; + case PD_RADIO: + *(long*)p->valueP = wRadioGetValue( (wChoice_p)p->control ); + break; + case PD_TOGGLE: + *(long*)p->valueP = wToggleGetValue( (wChoice_p)p->control ); + break; + case PD_LIST: + case PD_DROPLIST: + case PD_COMBOLIST: + *(wIndex_t*)p->valueP = wListGetIndex( (wList_p)p->control ); + break; + case PD_COLORLIST: + *(wDrawColor*)p->valueP = wColorSelectButtonGetColor( (wButton_p)p->control ); +#ifdef LATER + inx = wListGetIndex( (wList_p)p->control ); + *(wDrawColor*)p->valueP = colorTab[inx].color; +#endif + break; + case PD_FLOAT: + if (p->option & PDO_DIM) { + floatV = DecodeDistance( (wString_p)p->control, &valid ); + } else { + floatV = DecodeFloat( (wString_p)p->control, &valid ); + if (valid && (p->option & PDO_ANGLE) ) + floatV = NormalizeAngle( (angleSystem==ANGLE_POLAR)?floatV:-floatV ); + } + if ( valid ) + *(FLOAT_T*)p->valueP = floatV; + break; + case PD_STRING: + stringV = wStringGetValue( (wString_p)p->control ); + strcpy( (char*)p->valueP, stringV ); + break; + case PD_MESSAGE: + case PD_BUTTON: + case PD_DRAW: + case PD_TEXT: + case PD_MENU: + case PD_MENUITEM: + break; + } + } +} + + +static long ParamIntRestore( + paramGroup_p pg, + int class ) +{ + long change = 0; + int inx; + paramData_p p; + FLOAT_T valR; + char * valS; + paramOldData_t * oldP; + + for ( p=pg->paramPtr,inx=0; p<&pg->paramPtr[pg->paramCnt]; p++,inx++ ) { + oldP = (class==0)?&p->oldD:&p->demoD; + if ( (p->option&PDO_DLGIGNORE) != 0 ) + continue; + if (p->valueP == NULL) + continue; + switch ( p->type ) { + case PD_LONG: + if ( *(long*)p->valueP != oldP->l ) { + /*if ((p->option&PDO_NORSTUPD)==0)*/ + *(long*)p->valueP = oldP->l; + if (p->control) { + wStringSetValue( (wString_p)p->control, FormatLong( oldP->l ) ); + } + change |= (1L<<inx); + } + break; + case PD_RADIO: + if ( *(long*)p->valueP != oldP->l ) { + /*if ((p->option&PDO_NORSTUPD)==0)*/ + *(long*)p->valueP = oldP->l; + if (p->control) + wRadioSetValue( (wChoice_p)p->control, oldP->l ); + change |= (1L<<inx); + } + break; + case PD_TOGGLE: + if ( *(long*)p->valueP != oldP->l ) { + /*if ((p->option&PDO_NORSTUPD)==0)*/ + *(long*)p->valueP = oldP->l; + if (p->control) + wToggleSetValue( (wChoice_p)p->control, oldP->l ); + change |= (1L<<inx); + } + break; + case PD_LIST: + case PD_DROPLIST: + case PD_COMBOLIST: + if ( *(wIndex_t*)p->valueP != (wIndex_t)oldP->l ) { + /*if ((p->option&PDO_NORSTUPD)==0)*/ + *(wIndex_t*)p->valueP = (wIndex_t)oldP->l; + if (p->control) + wListSetIndex( (wList_p)p->control, (wIndex_t)oldP->l ); + change |= (1L<<inx); + } + break; + case PD_COLORLIST: + if ( *(wDrawColor*)p->valueP != oldP->dc ) { + /*if ((p->option&PDO_NORSTUPD)==0)*/ + *(wDrawColor*)p->valueP = oldP->dc; + if (p->control) + wColorSelectButtonSetColor( (wButton_p)p->control, oldP->dc ); /* COLORNOP */ + change |= (1L<<inx); + } + break; + case PD_FLOAT: + if ( *(FLOAT_T*)p->valueP != oldP->f ) { + /*if ((p->option&PDO_NORSTUPD)==0)*/ + *(FLOAT_T*)p->valueP = oldP->f; + if (p->control) { + valR = oldP->f; + if (p->option & PDO_DIM) { + if (p->option & PDO_SMALLDIM) + valS = FormatSmallDistance( valR ); + else + valS = FormatDistance( valR ); + } else { + if (p->option & PDO_ANGLE) + valR = NormalizeAngle( (angleSystem==ANGLE_POLAR)?valR:-valR ); + valS = FormatFloat( valR ); + } + wStringSetValue( (wString_p)p->control, valS ); + } + change |= (1L<<inx); + } + break; + case PD_STRING: + if ( oldP->s && strcmp((char*)p->valueP,oldP->s) != 0 ) { + /*if ((p->option&PDO_NORSTUPD)==0)*/ + strcpy( (char*)p->valueP, oldP->s ); + if (p->control) + wStringSetValue( (wString_p)p->control, oldP->s ); + change |= (1L<<inx); + } + break; + case PD_MESSAGE: + case PD_BUTTON: + case PD_DRAW: + case PD_TEXT: + case PD_MENU: + case PD_MENUITEM: + break; + } + } +#ifdef PGPROC + if (pg->proc) + pg->proc( PGACT_RESTORE, change ); +#endif + return change; +} + + +static void ParamIntSave( + paramGroup_p pg, + int class ) +{ + paramData_p p; + paramOldData_t * oldP; + + for ( p=pg->paramPtr; p<&pg->paramPtr[pg->paramCnt]; p++ ) { + oldP = (class==0)?&p->oldD:&p->demoD; + if (p->valueP) { + switch (p->type) { + case PD_LONG: + case PD_RADIO: + case PD_TOGGLE: + oldP->l = *(long*)p->valueP; + break; + case PD_LIST: + case PD_DROPLIST: + case PD_COMBOLIST: + oldP->l = *(wIndex_t*)p->valueP; + break; + case PD_COLORLIST: + oldP->dc = *(wDrawColor*)p->valueP; + break; + case PD_FLOAT: + oldP->f = *(FLOAT_T*)p->valueP; + break; + case PD_STRING: + if (oldP->s) + MyFree(oldP->s); + oldP->s = MyStrdup( (char*)p->valueP ); + break; + case PD_MESSAGE: + case PD_BUTTON: + case PD_DRAW: + case PD_TEXT: + case PD_MENU: + case PD_MENUITEM: + break; + } + } + } +} + +#ifdef LATER +static void ParamSave( paramGroup_p pg ) +{ + ParamIntSave( pg, 0 ); +} + +static long ParamRestore( paramGroup_p pg ) +{ + return ParamIntRestore( pg, 0 ); +} +#endif + +/**************************************************************************** + * + * + * + */ + +static dynArr_t paramGroups_da; +#define paramGroups(N) DYNARR_N( paramGroup_p, paramGroups_da, N ) + + + +EXPORT void ParamRegister( paramGroup_p pg ) +{ + paramData_p p; + const char * cp; + WDOUBLE_T tmpR; + long valL; + long rgb; + char prefName1[STR_SHORT_SIZE]; + const char *prefSect2, *prefName2; + + DYNARR_APPEND( paramGroup_p, paramGroups_da, 10 ); + paramGroups(paramGroups_da.cnt-1) = pg; + for ( p=pg->paramPtr; p<&pg->paramPtr[pg->paramCnt]; p++ ) { + p->group = pg; + if ( p->nameStr == NULL ) + continue; + sprintf( prefName1, "%s-%s", pg->nameStr, p->nameStr ); + if ( p->type != PD_MENUITEM ) { + (void)GetBalloonHelpStr( prefName1 ); + } + if (p->valueP == NULL || (p->option&PDO_NOPREF) != 0) + continue; + prefSect2 = PREFSECT; + prefName2 = prefName1; + if ( (p->option&PDO_MISC) ) { + prefSect2 = "misc"; + prefName2 = p->nameStr; + } else if ( (p->option&PDO_DRAW) ) { + prefSect2 = "draw"; + prefName2 = p->nameStr; + } else if ( (p->option&PDO_FILE) ) { + prefSect2 = "file"; + prefName2 = p->nameStr; + } else if ( (pg->options&PGO_PREFGROUP) ) { + prefSect2 = pg->nameStr; + prefName2 = p->nameStr; + } else if ( (pg->options&PGO_PREFMISC) ) { + prefSect2 = "misc"; + prefName2 = p->nameStr; + } else if ( (pg->options&PGO_PREFMISCGROUP) ) { + prefSect2 = "misc"; + } else if ( (pg->options&PGO_PREFDRAWGROUP) ) { + prefSect2 = "draw"; + } + cp = strchr( p->nameStr, '\t' ); + if ( cp ) { + /* *cp++ = 0; */ + prefSect2 = cp; + cp = strchr( cp, '\t' ); + if ( cp ) { + /* *cp++ = 0; */ + prefName2 = cp; + } + } + switch (p->type) { + case PD_LONG: + case PD_RADIO: + case PD_TOGGLE: + if ( !wPrefGetInteger( PREFSECT, prefName1, p->valueP, *(long*)p->valueP )) + wPrefGetInteger( prefSect2, prefName2, p->valueP, *(long*)p->valueP ); + break; + case PD_LIST: + case PD_DROPLIST: + case PD_COMBOLIST: + if ( (p->option&PDO_LISTINDEX) ) { + if (!wPrefGetInteger( PREFSECT, prefName1, &valL, *(wIndex_t*)p->valueP )) + wPrefGetInteger( prefSect2, prefName2, &valL, *(wIndex_t*)p->valueP ); + if ( p->control ) + wListSetIndex( (wList_p)p->control, (wIndex_t)valL ); + *(wIndex_t*)p->valueP = (wIndex_t)valL; + } else { + if (!p->control) + break; + cp = wPrefGetString( PREFSECT, prefName1 ); + if ( !cp ) + cp = wPrefGetString( prefSect2, prefName2 ); + if ( !cp ) + break; + *(wIndex_t*)p->valueP = wListFindValue( (wList_p)p->control, cp ); + } + break; + case PD_COLORLIST: + rgb = wDrawGetRGB( *(wDrawColor*)p->valueP ); + if (!wPrefGetInteger( PREFSECT, prefName1, &rgb, rgb )) + wPrefGetInteger( prefSect2, prefName2, &rgb, rgb ); + *(wDrawColor*)p->valueP = wDrawFindColor( rgb ); + break; + case PD_FLOAT: + if (!wPrefGetFloat( PREFSECT, prefName1, &tmpR, *(FLOAT_T*)p->valueP )) + wPrefGetFloat( prefSect2, prefName2, &tmpR, *(FLOAT_T*)p->valueP ); + *(FLOAT_T*)p->valueP = tmpR; + break; + case PD_STRING: + cp = wPrefGetString( PREFSECT, prefName1 ); + if (!cp) + wPrefGetString( prefSect2, prefName2 ); + if (cp) + strcpy( p->valueP, cp ); + else + ((char*)p->valueP)[0] = '\0'; + break; + case PD_MESSAGE: + case PD_BUTTON: + case PD_DRAW: + case PD_TEXT: + case PD_MENU: + case PD_MENUITEM: + case PD_BITMAP: + break; + } + } +} + + + + +EXPORT void ParamUpdatePrefs( void ) +{ + int inx; + paramGroup_p pg; + paramData_p p; + long rgb; + char prefName[STR_SHORT_SIZE]; + int len; + int col; + char * cp; + static wPos_t * colWidths; + static int maxColCnt = 0; + paramListData_t * listDataP; + + for ( inx=0; inx<paramGroups_da.cnt; inx++ ) { + pg = paramGroups(inx); + for ( p=pg->paramPtr; p<&pg->paramPtr[pg->paramCnt]; p++ ) { + if (p->valueP == NULL || p->nameStr == NULL || (p->option&PDO_NOPREF)!=0 ) + continue; + if ( (p->option&PDO_DLGIGNORE) != 0 ) + continue; + sprintf( prefName, "%s-%s", pg->nameStr, p->nameStr ); + switch ( p->type ) { + case PD_LONG: + case PD_RADIO: + case PD_TOGGLE: + wPrefSetInteger( PREFSECT, prefName, *(long*)p->valueP ); + break; + case PD_LIST: + listDataP = (paramListData_t*)p->winData; + if ( p->control && listDataP->colCnt > 0 ) { + if ( maxColCnt < listDataP->colCnt ) { + if ( maxColCnt == 0 ) + colWidths = (wPos_t*)MyMalloc( listDataP->colCnt * sizeof * colWidths ); + else + colWidths = (wPos_t*)MyRealloc( colWidths, listDataP->colCnt * sizeof * colWidths ); + maxColCnt = listDataP->colCnt; + } + len = wListGetColumnWidths( (wList_p)p->control, listDataP->colCnt, colWidths ); + cp = message; + for ( col=0; col<len; col++ ) { + sprintf( cp, "%d ", colWidths[col] ); + cp += strlen(cp); + } + *cp = '\0'; + len = strlen( prefName ); + strcpy( prefName+len, "-columnwidths" ); + wPrefSetString( PREFSECT, prefName, message ); + prefName[len] = '\0'; + } + case PD_DROPLIST: + case PD_COMBOLIST: + if ( (p->option&PDO_LISTINDEX) ) { + wPrefSetInteger( PREFSECT, prefName, *(wIndex_t*)p->valueP ); + } else { + if (p->control) { + wListGetValues( (wList_p)p->control, message, sizeof message, NULL, NULL ); + wPrefSetString( PREFSECT, prefName, message ); + } + } + break; + case PD_COLORLIST: + rgb = wDrawGetRGB( *(wDrawColor*)p->valueP ); + wPrefSetInteger( PREFSECT, prefName, rgb ); + break; + case PD_FLOAT: + wPrefSetFloat( PREFSECT, prefName, *(FLOAT_T*)p->valueP ); + break; + case PD_STRING: + wPrefSetString( PREFSECT, prefName, (char*)p->valueP ); + break; + case PD_MESSAGE: + case PD_BUTTON: + case PD_DRAW: + case PD_TEXT: + case PD_MENU: + case PD_MENUITEM: + case PD_BITMAP: + break; + } + } + } +} + +EXPORT void ParamGroupRecord( + paramGroup_p pg ) +{ + paramData_p p; + long rgb; + + if (recordF == NULL) + return; + for ( p=pg->paramPtr; p<&pg->paramPtr[pg->paramCnt]; p++ ) { + if ( (p->option&PDO_NORECORD) != 0 || p->valueP == NULL || p->nameStr == NULL ) + continue; + if ( (p->option&PDO_DLGIGNORE) != 0 ) + continue; + switch ( p->type ) { + case PD_LONG: + case PD_RADIO: + case PD_TOGGLE: + fprintf( recordF, "PARAMETER %s %s %ld\n", pg->nameStr, p->nameStr, *(long*)p->valueP ); + break; + case PD_LIST: + case PD_DROPLIST: + case PD_COMBOLIST: + if (p->control) + wListGetValues( (wList_p)p->control, message, sizeof message, NULL, NULL ); + else + message[0] = '\0'; + fprintf( recordF, "PARAMETER %s %s %d %s\n", pg->nameStr, p->nameStr, *(wIndex_t*)p->valueP, message ); + break; + case PD_COLORLIST: + rgb = wDrawGetRGB( *(wDrawColor*)p->valueP ); + fprintf( recordF, "PARAMETER %s %s %ld\n", + pg->nameStr, p->nameStr, rgb ); + break; + case PD_FLOAT: + fprintf( recordF, "PARAMETER %s %s %0.3f\n", pg->nameStr, p->nameStr, *(FLOAT_T*)p->valueP ); + break; + case PD_STRING: + fprintf( recordF, "PARAMETER %s %s %s\n", pg->nameStr, p->nameStr, (char*)p->valueP ); + break; + case PD_MESSAGE: + case PD_BUTTON: + case PD_DRAW: + case PD_TEXT: + case PD_MENU: + case PD_MENUITEM: + break; + } + } + if (pg->nameStr) + fprintf( recordF, "PARAMETER GROUP %s\n", pg->nameStr ); + fflush( recordF ); +} + + +EXPORT void ParamStartRecord( void ) +{ + int inx; + paramGroup_p pg; + + if (recordF == NULL) + return; + for ( inx=0; inx<paramGroups_da.cnt; inx++ ) { + pg = paramGroups(inx); + if (pg->options&PGO_RECORD) { + ParamGroupRecord( pg ); + } + } +} + + +EXPORT void ParamRestoreAll( void ) +{ + int inx; + paramGroup_p pg; + + for ( inx=0; inx<paramGroups_da.cnt; inx++ ) { + pg = paramGroups(inx); + ParamIntRestore( pg, 1 ); + } + if ( paramCheckErrorCount > 0 ) { + NoticeMessage( "PARAMCHECK: %d errors", "Ok", NULL, paramCheckErrorCount ); + } +} + + +EXPORT void ParamSaveAll( void ) +{ + int inx; + + for ( inx=0; inx<paramGroups_da.cnt; inx++ ) { + ParamIntSave( paramGroups(inx), 1 ); + paramGroups(inx)->action = 0; + } + paramCheckErrorCount = 0; +} + + +static void ParamButtonPush( void * dp ) +{ + paramData_p p = (paramData_p)dp; + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) { + fprintf( recordF, "PARAMETER %s %s\n", p->group->nameStr, p->nameStr ); + fflush( recordF ); + } + if ( (p->option&PDO_NOPSHACT)==0 ) { + if ( p->valueP ) + ((wButtonCallBack_p)(p->valueP))( p->context ); + else if ( p->group->changeProc) + p->group->changeProc( p->group, p-p->group->paramPtr, NULL); + } +} + + +static void ParamChoicePush( long valL, void * dp ) +{ + paramData_p p = (paramData_p)dp; + + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) { + fprintf( recordF, "PARAMETER %s %s %ld\n", p->group->nameStr, p->nameStr, valL ); + fflush( recordF ); + } + if ( (p->option&PDO_NOPSHUPD)==0 && p->valueP) + *((long*)(p->valueP)) = valL; + if ( (p->option&PDO_NOPSHACT)==0 && p->group->changeProc) + p->group->changeProc( p->group, p-p->group->paramPtr, &valL); +} + + +static void ParamIntegerPush( const char * val, void * dp ) +{ + paramData_p p = (paramData_p)dp; + long valL; + char * cp; + paramIntegerRange_t * irangeP; + + while ( isspace(*val)) val++; + valL = strtol( val, &cp, 10 ); + + wControlSetBalloon( p->control, 0, -5, NULL ); + if ( val == cp ) { + wControlSetBalloon( p->control, 0, -5, _("Invalid Number") ); + return; + } + irangeP = (paramIntegerRange_t*)p->winData; + if ( ( (irangeP->rangechecks&PDO_NORANGECHECK_HIGH) == 0 && valL > irangeP->high ) || + ( (irangeP->rangechecks&PDO_NORANGECHECK_LOW) == 0 && valL < irangeP->low ) ) { + if ( (irangeP->rangechecks&(PDO_NORANGECHECK_HIGH|PDO_NORANGECHECK_LOW)) == PDO_NORANGECHECK_HIGH ) + sprintf( message, _("Enter a value > %ld"), irangeP->low ); + else if ( (irangeP->rangechecks&(PDO_NORANGECHECK_HIGH|PDO_NORANGECHECK_LOW)) == PDO_NORANGECHECK_LOW ) + sprintf( message, _("Enter a value < %ld"), irangeP->high ); + else + sprintf( message, _("Enter a value between %ld and %ld"), irangeP->low, irangeP->high ); + wControlSetBalloon( p->control, 0, -5, message ); + return; + } + wControlSetBalloon( p->control, 0, -5, NULL ); + + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) { + fprintf( recordF, "PARAMETER %s %s %ld\n", p->group->nameStr, p->nameStr, valL ); + fflush( recordF ); + } + if ( (p->option&PDO_NOPSHUPD)==0 && p->valueP) + *((long*)(p->valueP)) = valL; + if ( (p->option&PDO_NOPSHACT)==0 && p->group->changeProc) + p->group->changeProc( p->group, p-p->group->paramPtr, &valL); +} + +/** + * Checks the entered value in a float field. Accepts data entered in the different + * formats for dimensions. Compares the value against limits if specified in that + * entry field description. + * + * \param val IN the vale to check + * \param dp IN the field description + */ + +static void ParamFloatPush( const char * val, void * dp ) +{ + paramData_p p = (paramData_p)dp; + FLOAT_T valF; + BOOL_T valid; + paramFloatRange_t * frangeP; + + if (p->option & PDO_DIM) { + valF = DecodeDistance( (wString_p)p->control, &valid ); + } else { + valF = DecodeFloat( (wString_p)p->control, &valid ); + if (p->option & PDO_ANGLE) + valF = NormalizeAngle( (angleSystem==ANGLE_POLAR)?valF:-valF ); + } + wControlSetBalloon( p->control, 0, -5, NULL ); + if ( !valid ) { + wControlSetBalloon( p->control, 0, -5, decodeErrorStr ); + return; + } + frangeP = (paramFloatRange_t*)p->winData; + if ( ( (frangeP->rangechecks&PDO_NORANGECHECK_HIGH) == 0 && valF > frangeP->high ) || + ( (frangeP->rangechecks&PDO_NORANGECHECK_LOW) == 0 && valF < frangeP->low ) ) { + if ( (frangeP->rangechecks&(PDO_NORANGECHECK_HIGH|PDO_NORANGECHECK_LOW)) == PDO_NORANGECHECK_HIGH ) + sprintf( message, _("Enter a value > %s"), + (p->option&PDO_DIM)?FormatDistance(frangeP->low):FormatFloat(frangeP->low) ); + else if ( (frangeP->rangechecks&(PDO_NORANGECHECK_HIGH|PDO_NORANGECHECK_LOW)) == PDO_NORANGECHECK_LOW ) + sprintf( message, _("Enter a value < %s"), + (p->option&PDO_DIM)?FormatDistance(frangeP->high):FormatFloat(frangeP->high) ); + else + sprintf( message, _("Enter a value between %s and %s"), + (p->option&PDO_DIM)?FormatDistance(frangeP->low):FormatFloat(frangeP->low), + (p->option&PDO_DIM)?FormatDistance(frangeP->high):FormatFloat(frangeP->high) ); + wControlSetBalloon( p->control, 0, -5, message ); + return; + } + wControlSetBalloon( p->control, 0, -5, NULL ); + + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) { + fprintf( recordF, "PARAMETER %s %s %0.6f\n", p->group->nameStr, p->nameStr, valF ); + fflush( recordF ); + } + if ( (p->option&PDO_NOPSHUPD)==0 && p->valueP) + *((FLOAT_T*)(p->valueP)) = valF; + if ( (p->option&PDO_NOPSHACT)==0 && p->group->changeProc && strlen( val )) + p->group->changeProc( p->group, p-p->group->paramPtr, &valF ); +} + + +static void ParamStringPush( const char * val, void * dp ) +{ + paramData_p p = (paramData_p)dp; + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) { + fprintf( recordF, "PARAMETER %s %s %s\n", p->group->nameStr, p->nameStr, val ); + fflush( recordF ); + } + if ( (p->option&PDO_NOPSHUPD)==0 && p->valueP) + strcpy( (char*)p->valueP, val ); + if ( (p->option&PDO_NOPSHACT)==0 && p->group->changeProc) + p->group->changeProc( p->group, p-p->group->paramPtr, CAST_AWAY_CONST val ); +} + + +static void ParamListPush( wIndex_t inx, const char * val, wIndex_t op, void * dp, void * itemContext ) +{ + paramData_p p = (paramData_p)dp; + long valL; + + switch (p->type) { + case PD_LIST: + case PD_DROPLIST: + case PD_COMBOLIST: + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) { + fprintf( recordF, "PARAMETER %s %s %d %s\n", p->group->nameStr, p->nameStr, inx, val ); + fflush( recordF ); + } + if ( (p->option&PDO_NOPSHUPD)==0 && p->valueP) + *(wIndex_t*)(p->valueP) = inx; + if ( (p->option&PDO_NOPSHACT)==0 && p->group->changeProc ) { + valL = inx; + p->group->changeProc( p->group, p-p->group->paramPtr, &valL ); + } + break; +#ifdef LATER + case PD_COLORLIST: + dc = colorTab[inx].color; + rgb = wDrawGetRGB( dc ); + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) { + fprintf( recordF, "PARAMETER %s %s %ld\n", + p->group->nameStr, p->nameStr, rgb ); + fflush( recordF ); + } + if ( (p->option&PDO_NOPSHUPD)==0 && p->valueP) + *(wDrawColor*)(p->valueP) = dc; + if ( (p->option&PDO_NOPSHACT)==0 && p->group->changeProc ) { + ; /* COLOR NOP */ + } + break; +#endif + default: + ; + } +} + + +EXPORT void ParamMenuPush( void * dp ) +{ + paramData_p p = (paramData_p)dp; + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) { + fprintf( recordF, "PARAMETER %s %s\n", p->group->nameStr, p->nameStr ); + fflush( recordF ); + } + if ( (p->option&PDO_NOPSHACT)==0 && p->valueP ) + ((wMenuCallBack_p)(p->valueP))( p->context ); +} + + +static void ParamColorSelectPush( void * dp, wDrawColor dc ) +{ + paramData_p p = (paramData_p)dp; + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) { + fprintf( recordF, "PARAMETER %s %s %ld\n", p->group->nameStr, p->nameStr, wDrawGetRGB(dc) ); + fflush( recordF ); + } + if ( (p->option&PDO_NOPSHUPD)==0 && p->valueP) + *(wDrawColor*)(p->valueP) = dc; + if ( (p->option&PDO_NOPSHACT)==0 && p->group->changeProc ) + p->group->changeProc( p->group, p-p->group->paramPtr, &dc ); +} + + +static void ParamDrawRedraw( wDraw_p d, void * dp, wPos_t w, wPos_t h ) +{ + paramData_p p = (paramData_p)dp; + paramDrawData_t * ddp = (paramDrawData_t*)p->winData; + if ( ddp->redraw ) + ddp->redraw( d, p->context, w, h ); +} + + +static void ParamDrawAction( wDraw_p d, void * dp, wAction_t a, wPos_t w, wPos_t h ) +{ + paramData_p p = (paramData_p)dp; + paramDrawData_t * ddp = (paramDrawData_t*)p->winData; + coOrd pos; + ddp->d->Pix2CoOrd( ddp->d, w, h, &pos ); + if ( recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) { + fprintf( recordF, "PARAMETER %s %s %d %0.3f %0.3f\n", p->group->nameStr, p->nameStr, a, pos.x, pos.y ); + fflush( recordF ); + } + if ( (p->option&PDO_NOPSHACT)== 0 && ddp->action ) + ddp->action( a, pos ); +} + + +static void ParamButtonOk( + paramGroup_p group ) +{ + if ( recordF && group->nameStr ) + fprintf( recordF, "PARAMETER %s %s\n", group->nameStr, "ok" ); { + fflush( recordF ); + } + if ( group->okProc ) + group->okProc( group->okProc==(paramActionOkProc)wHide?((void*)group->win):group ); +} + + +static void ParamButtonCancel( + paramGroup_p group ) +{ + if ( recordF && group->nameStr ) { + fprintf( recordF, "PARAMETER %s %s\n", group->nameStr, "cancel" ); + fflush( recordF ); + } + if ( group->cancelProc ) + group->cancelProc( group->win ); +} + + +#ifdef LATER +EXPORT void ParamChange( paramData_p p ) +{ + FLOAT_T tmpR; + + if (p->valueP==NULL) + return; + + switch (p->type) { + case PD_LONG: + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) + fprintf( recordF, "PARAMETER %s %s %ld\n", p->group->nameStr, p->nameStr, *(long*)p->valueP ); +#ifdef LATER + if ( p->control && (p->option&PDO_NOCONTUPD) == 0 ) { + wStringSetValue( (wString_p)p->control, FormatLong( *(long*)p->valueP ) ); + } +#endif + break; + case PD_RADIO: + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) + fprintf( recordF, "PARAMETER %s %s %ld\n", p->group->nameStr, p->nameStr, *(long*)p->valueP ); +#ifdef LATER + if ( p->control && (p->option&PDO_NOCONTUPD) == 0 ) + wRadioSetValue( (wChoice_p)p->control, *(long*)p->valueP ); +#endif + break; + case PD_TOGGLE: + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) + fprintf( recordF, "PARAMETER %s %s %ld\n", p->group->nameStr, p->nameStr, *(long*)p->valueP ); +#ifdef LATER + if ( p->control && (p->option&PDO_NOCONTUPD) == 0 ) + wToggleSetValue( (wChoice_p)p->control, *(long*)p->valueP ); +#endif + break; + case PD_LIST: + case PD_DROPLIST: + case PD_COMBOLIST: + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) { + fprintf( recordF, "PARAMETER %s %s %d %s\n", p->group->nameStr, p->nameStr, *(wIndex_t*)p->valueP, ??? ); + } +#ifdef LATER + if ( p->control && (p->option&PDO_NOCONTUPD) == 0 ) + wListSetIndex( (wList_p)p->control, *(wIndex_t*)p->valueP ); +#endif + break; + case PD_COLORLIST: + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) + fprintf( recordF, "PARAMETER %s %s %ld\n", p->group->nameStr, p->nameStr, rgb ); +#ifdef LATER + if ( p->control && (p->option&PDO_NOCONTUPD) == 0 ) + wColorSelectButtonSetColor( (wButton_p)p->control, wDrawFindRGB(rgb) ); +#endif + break; + case PD_FLOAT: + tmpR = *(FLOAT_T*)p->valueP; + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) + fprintf( recordF, "PARAMETER %s %s %0.6f\n", p->group->nameStr, p->nameStr, tmpR ); +#ifdef LATER + if ( p->control && (p->option&PDO_NOCONTUPD) == 0 ) { + if (p->option&PDO_DIM) +#endif + if (p->option&PDO_ANGLE) + tmpR = NormalizeAngle( (angleSystem==ANGLE_POLAR)?tmpR:-tmpR ); + wStringSetValue( (wString_p)p->control, tmpR ); + } + break; + case PD_STRING: + if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) + fprintf( recordF, "PARAMETER %s %s %s\n", p->group->nameStr, p->nameStr, (char*)p->valueP ); +#ifdef LATER + if ( p->control && (p->option&PDO_NOCONTUPD) == 0 ) + wStringSetValue( (wString_p)p->control, (char*)p->valueP ); +#endif + break; + case PD_MESSAGE: + case PD_BUTTON: + case PD_DRAW: + case PD_TEXT: + case PD_MENU: + case PD_MENUITEM: + break; + } +} +#endif + + +EXPORT int paramHiliteFast = FALSE; +EXPORT void ParamHilite( + wWin_p win, + wControl_p control, + BOOL_T hilite ) +{ + if ( win != NULL && wWinIsVisible(win) == FALSE ) return; + if ( control == NULL ) return; + if ( !paramTogglePlaybackHilite ) return; + if ( hilite ) { + wControlHilite( control, TRUE ); + wFlush(); + if ( !paramHiliteFast ) + wPause(500); + } else { + if ( !paramHiliteFast ) + wPause(500); + wControlHilite( control, FALSE ); + wFlush(); + } +} + + +static void ParamPlayback( char * line ) +{ + paramGroup_p pg; + paramData_p p; + long valL; + FLOAT_T valF, valF1; + int len, len1, len2; + wIndex_t inx; + void * listContext, * itemContext; + long rgb; + wDrawColor dc; + wButton_p button; + paramDrawData_t * ddp; + wAction_t a; + coOrd pos; + char * valS; + char *oldLocale = NULL; + + if ( strncmp( line, "GROUP ", 6 ) == 0 ) { +#ifdef PGPROC + for ( inx=0; inx<paramGroups_da.cnt; inx++ ) { + pg = paramGroups(inx); + if ( pg->name && strncmp( line+6, pg->name, strlen( pg->name ) ) == 0 ) { + if ( pg->proc ) { + pg->proc( PGACT_PARAM, pg->action ); + } + pg->action = 0; + } + } +#endif + return; + } + + for ( inx=0; inx<paramGroups_da.cnt; inx++ ) { + pg = paramGroups(inx); + if ( pg->nameStr == NULL ) + continue; + len1 = strlen( pg->nameStr ); + if ( strncmp( pg->nameStr, line, len1 ) != 0 || + line[len1] != ' ' ) + continue; + for ( p=pg->paramPtr,inx=0; inx<pg->paramCnt; p++,inx++ ) { + if ( p->nameStr == NULL ) + continue; + len2 = strlen( p->nameStr ); + if ( strncmp(p->nameStr, line+len1+1, len2) != 0 || + (line[len1+1+len2] != ' ' && line[len1+1+len2] != '\0') ) + continue; + len = len1 + 1 + len2 + 1; + if ( p->type != PD_DRAW && p->type != PD_MESSAGE && p->type != PD_MENU && p->type != PD_MENUITEM ) + ParamHilite( p->group->win, p->control, TRUE ); + switch (p->type) { + case PD_BUTTON: + if (p->valueP) + ((wButtonCallBack_p)(p->valueP))( p->context ); + if (playbackTimer == 0 && p->control) { + wButtonSetBusy( (wButton_p)p->control, TRUE ); + wFlush(); + wPause( 500 ); + wButtonSetBusy( (wButton_p)p->control, FALSE ); + wFlush(); + } + break; + case PD_LONG: + valL = atol( line+len ); + if (p->valueP) + *(long*)p->valueP = valL; + if (p->control) { + wStringSetValue( (wString_p)p->control, FormatLong( valL ) ); + wFlush(); + } + if (pg->changeProc) + pg->changeProc( pg, inx, &valL ); + break; + case PD_RADIO: + valL = atol( line+len ); + if (p->valueP) + *(long*)p->valueP = valL; + if (p->control) { + wRadioSetValue( (wChoice_p)p->control, valL ); + wFlush(); + } + if (pg->changeProc) + pg->changeProc( pg, inx, &valL ); + break; + case PD_TOGGLE: + valL = atol( line+len ); + if (p->valueP) + *(long*)p->valueP = valL; + if (p->control) { + wToggleSetValue( (wChoice_p)p->control, valL ); + wFlush(); + } + if (pg->changeProc) + pg->changeProc( pg, inx, &valL ); + break; + case PD_LIST: + case PD_DROPLIST: + case PD_COMBOLIST: + line += len; + valL = strtol( line, &valS, 10 ); + if ( valS ) + valS++; + else + valS = ""; + if ( p->control != NULL ) { + if ( (p->option&PDO_LISTINDEX) == 0 ) { + if ( valL < 0 ) { + wListSetValue( (wList_p)p->control, valS ); + } else { + valL = wListFindValue( (wList_p)p->control, valS ); + if (valL < 0) { + NoticeMessage( MSG_PLAYBACK_LISTENTRY, _("Ok"), NULL, line ); + break; + } + wListSetIndex( (wList_p)p->control, (wIndex_t)valL ); + } + } else { + wListSetIndex( (wList_p)p->control, (wIndex_t)valL ); + } + wFlush(); + wListGetValues( (wList_p)p->control, message, sizeof message, &listContext, &itemContext ); + } else if ( (p->option&PDO_LISTINDEX) == 0 ) { + break; + } + if (p->valueP) + *(wIndex_t*)p->valueP = (wIndex_t)valL; + if (pg->changeProc) { + pg->changeProc( pg, inx, &valL ); + } + break; + case PD_COLORLIST: + line += len; + rgb = atol( line ); + dc = wDrawFindColor( rgb ); + if ( p->control) + wColorSelectButtonSetColor( (wButton_p)p->control, dc ); +#ifdef LATER + valL = ColorTabLookup( dc ); + if (p->control) { + wListSetIndex( (wList_p)p->control, (wIndex_t)valL ); + wFlush(); + } +#endif + if (p->valueP) + *(wDrawColor*)p->valueP = dc; + if (pg->changeProc) { + /* COLORNOP */ + pg->changeProc( pg, inx, &valL ); + } + break; + case PD_FLOAT: + oldLocale = SaveLocale("C"); + valF = valF1 = atof( line+len ); + RestoreLocale(oldLocale); + if (p->valueP) + *(FLOAT_T*)p->valueP = valF; + if (p->option&PDO_DIM) { + if ( p->option&PDO_SMALLDIM ) + valS = FormatSmallDistance( valF ); + else + valS = FormatDistance( valF ); + } else { + if (p->option&PDO_ANGLE) + valF1 = NormalizeAngle( (angleSystem==ANGLE_POLAR)?valF1:-valF1 ); + valS = FormatFloat( valF ); + } + if (p->control) { + wStringSetValue( (wString_p)p->control, valS ); + wFlush(); + } + if (pg->changeProc) + pg->changeProc( pg, inx, &valF ); + break; + case PD_STRING: + line += len; + while ( *line == ' ' ) line++; + Stripcr( line ); + if (p->valueP) + strcpy( (char*)p->valueP, line ); + if (p->control) { + wStringSetValue( (wString_p)p->control, line ); + wFlush(); + } + if (pg->changeProc) + pg->changeProc( pg, inx, line ); + break; + case PD_DRAW: + ddp = (paramDrawData_t*)p->winData; + if ( ddp->action == NULL ) + break; + a = (wAction_t)strtol( line+len, &line, 10 ); + pos.x = strtod( line, &line ); + pos.y = strtod( line, NULL ); + PlaybackMouse( ddp->action, ddp->d, a, pos, drawColorBlack ); + break; + case PD_MESSAGE: + case PD_TEXT: + case PD_MENU: + break; + case PD_MENUITEM: + if (p->valueP) { + if ( (p->option&IC_PLAYBACK_PUSH) != 0 ) + PlaybackButtonMouse( (wIndex_t)(long)p->context ); + ((wButtonCallBack_p)(p->valueP))( p->context ); + } + break; + } + if ( p->type != PD_DRAW && p->type != PD_MESSAGE && p->type != PD_MENU && p->type != PD_MENUITEM ) + ParamHilite( p->group->win, p->control, FALSE ); +#ifdef HUH + pg->action |= p->change; +#endif + return; + } + button = NULL; + if ( strcmp("ok", line+len1+1) == 0 ) { + ParamHilite( pg->win, (wControl_p)pg->okB, TRUE ); + if ( pg->okProc ) + pg->okProc( pg ); + button = pg->okB; + } else if ( strcmp("cancel", line+len1+1) == 0 ) { + ParamHilite( pg->win, (wControl_p)pg->cancelB, TRUE ); + if ( pg->cancelProc ) + pg->cancelProc( pg->win ); + button = pg->cancelB; + } + if ( playbackTimer == 0 && button ) { + wButtonSetBusy( button, TRUE ); + wFlush(); + wPause( 500 ); + wButtonSetBusy( button, FALSE ); + wFlush(); + } + ParamHilite( pg->win, (wControl_p)button, FALSE ); + if ( !button ) + NoticeMessage( "Unknown PARAM: %s", _("Ok"), NULL, line ); + return; + } + NoticeMessage( "Unknown PARAM: %s", _("Ok"), NULL, line ); +} + + +static void ParamCheck( char * line ) +{ + paramGroup_p pg; + paramData_p p; + long valL; + FLOAT_T valF, diffF; + int len, len1, len2; + wIndex_t inx; + void * listContext, * itemContext; + char * valS; + char * expVal=NULL, * actVal=NULL; + char expNum[20], actNum[20]; + BOOL_T hasError = FALSE; + FILE * f; + + for ( inx=0; inx<paramGroups_da.cnt; inx++ ) { + pg = paramGroups(inx); + if ( pg->nameStr == NULL ) + continue; + len1 = strlen( pg->nameStr ); + if ( strncmp( pg->nameStr, line, len1 ) != 0 || + line[len1] != ' ' ) + continue; + for ( p=pg->paramPtr,inx=0; inx<pg->paramCnt; p++,inx++ ) { + if ( p->nameStr == NULL ) + continue; + len2 = strlen( p->nameStr ); + if ( strncmp(p->nameStr, line+len1+1, len2) != 0 || + (line[len1+1+len2] != ' ' && line[len1+1+len2] != '\0') ) + continue; + if ( p->valueP == NULL ) + return; + len = len1 + 1 + len2 + 1; + switch (p->type) { + case PD_BUTTON: + break; + case PD_LONG: + case PD_RADIO: + case PD_TOGGLE: + valL = atol( line+len ); + if ( *(long*)p->valueP != valL ) { + sprintf( expNum, "%ld", valL ); + sprintf( actNum, "%ld", *(long*)p->valueP ); + expVal = expNum; + actVal = actNum; + hasError = TRUE; + } + break; + case PD_LIST: + case PD_DROPLIST: + case PD_COMBOLIST: + line += len; + if ( p->control == NULL ) + break; + valL = strtol( line, &valS, 10 ); + if ( valS ) { + if ( valS[0] == ' ' ) + valS++; + } else { + valS = ""; + } + if ( (p->option&PDO_LISTINDEX) != 0 ) { + if ( *(long*)p->valueP != valL ) { + sprintf( expNum, "%ld", valL ); + sprintf( actNum, "%d", *(wIndex_t*)p->valueP ); + expVal = expNum; + actVal = actNum; + hasError = TRUE; + } + } else { + wListGetValues( (wList_p)p->control, message, sizeof message, &listContext, &itemContext ); + if ( strcasecmp( message, valS ) != 0 ) { + expVal = valS; + actVal = message; + hasError = TRUE; + } + } + break; + case PD_COLORLIST: + break; + case PD_FLOAT: + valF = atof( line+len ); + diffF = fabs( *(FLOAT_T*)p->valueP - valF ); + if ( diffF > 0.001 ) { + sprintf( expNum, "%0.3f", valF ); + sprintf( actNum, "%0.3f", *(FLOAT_T*)p->valueP ); + expVal = expNum; + actVal = actNum; + hasError = TRUE; + } + break; + case PD_STRING: + line += len; + while ( *line == ' ' ) line++; + valS = CAST_AWAY_CONST wStringGetValue( (wString_p)p->control ); + if ( strcasecmp( line, (char*)p->valueP ) != 0 ) { + expVal = line; + actVal = (char*)p->valueP; + hasError = TRUE; + } + break; + case PD_DRAW: + case PD_MESSAGE: + case PD_TEXT: + case PD_MENU: + case PD_MENUITEM: + break; + } + if ( hasError ) { + f = fopen( "error.log", "a" ); + if ( f==NULL ) { + NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, "PARAMCHECK LOG", "error.log", strerror(errno) ); + } else { + fprintf( f, "CHECK: %s:%d: %s-%s: exp: %s, act=%s\n", + paramFileName, paramLineNum, pg->nameStr, p->nameStr, expVal, actVal ); + fclose( f ); + } + if ( paramCheckShowErrors ) + NoticeMessage( "CHECK: %d: %s-%s: exp: %s, act=%s", _("Ok"), NULL, paramLineNum, pg->nameStr, p->nameStr, expVal, actVal ); + paramCheckErrorCount++; + } + return; + } + } + NoticeMessage( "Unknown PARAMCHECK: %s", _("Ok"), NULL, line ); +} + +/* + * + */ + + + +static void ParamCreateControl( + paramData_p pd, + char * helpStr, + wPos_t xx, + wPos_t yy ) +{ + paramFloatRange_t * floatRangeP; + paramIntegerRange_t * integerRangeP; + paramDrawData_t * drawDataP; + paramTextData_t * textDataP; + paramListData_t * listDataP; + wIcon_p iconP; + wDrawColor color = wDrawColorBlack; + + wWin_p win; + wPos_t w; + wPos_t colWidth; + static wPos_t *colWidths; + static wBool_t *colRightJust; + static wBool_t maxColCnt = 0; + int col; + const char *cp; + char *cq; + static wMenu_p menu = NULL; + + if ( ( win = pd->group->win ) == NULL ) + win = mainW; + + + switch (pd->type) { + case PD_FLOAT: + floatRangeP = pd->winData; + w = floatRangeP->width?floatRangeP->width:100; + pd->control = (wControl_p)wStringCreate( win, xx, yy, helpStr, _(pd->winLabel), pd->winOption, w, NULL, 0, ParamFloatPush, pd ); + break; + case PD_LONG: + integerRangeP = pd->winData; + w = integerRangeP->width?integerRangeP->width:100; + pd->control = (wControl_p)wStringCreate( win, xx, yy, helpStr, _(pd->winLabel), pd->winOption, w, NULL, 0, ParamIntegerPush, pd ); + break; + case PD_STRING: + w = pd->winData?(wPos_t)(long)pd->winData:(wPos_t)250; + pd->control = (wControl_p)wStringCreate( win, xx, yy, helpStr, _(pd->winLabel), pd->winOption, w, (pd->option&PDO_NOPSHUPD)?NULL:pd->valueP, 0, ParamStringPush, pd ); + break; + case PD_RADIO: + pd->control = (wControl_p)wRadioCreate( win, xx, yy, helpStr, _(pd->winLabel), pd->winOption, pd->winData, NULL, ParamChoicePush, pd ); + break; + case PD_TOGGLE: + pd->control = (wControl_p)wToggleCreate( win, xx, yy, helpStr, _(pd->winLabel), pd->winOption, pd->winData, NULL, ParamChoicePush, pd ); + break; + case PD_LIST: + listDataP = (paramListData_t*)pd->winData; + if ( listDataP->colCnt > 1 ) { + if ( maxColCnt < listDataP->colCnt ) { + if ( maxColCnt == 0 ) { + colWidths = (wPos_t*)MyMalloc( listDataP->colCnt * sizeof *colWidths ); + colRightJust = (wBool_t*)MyMalloc( listDataP->colCnt * sizeof *colRightJust ); + } else { + colWidths = (wPos_t*)MyRealloc( colWidths, listDataP->colCnt * sizeof *colWidths ); + colRightJust = (wBool_t*)MyRealloc( colRightJust, listDataP->colCnt * sizeof *colRightJust ); + } + maxColCnt = listDataP->colCnt; + } + for ( col=0; col<listDataP->colCnt; col++ ) { + colRightJust[col] = listDataP->colWidths[col]<0; + colWidths[col] = abs(listDataP->colWidths[col]); + } + sprintf( message, "%s-%s-%s", pd->group->nameStr, pd->nameStr, "columnwidths" ); + cp = wPrefGetString( PREFSECT, message ); + if ( cp != NULL ) { + for ( col=0; col<listDataP->colCnt; col++ ) { + colWidth = (wPos_t)strtol( cp, &cq, 10 ); + if ( cp == cq ) + break; + colWidths[col] = colWidth; + cp = cq; + } + } + } + pd->control = (wControl_p)wListCreate( win, xx, yy, helpStr, _(pd->winLabel), + pd->winOption, listDataP->number, listDataP->width, listDataP->colCnt, + (listDataP->colCnt>1?colWidths:NULL), + (listDataP->colCnt>1?colRightJust:NULL), + listDataP->colTitles, NULL, ParamListPush, pd ); + listDataP->height = wControlGetHeight( pd->control ); + break; + case PD_DROPLIST: + w = pd->winData?(wPos_t)(long)pd->winData:(wPos_t)100; + pd->control = (wControl_p)wDropListCreate( win, xx, yy, helpStr, _(pd->winLabel), pd->winOption, 10, w, NULL, ParamListPush, pd ); + break; + case PD_COMBOLIST: + listDataP = (paramListData_t*)pd->winData; + pd->control = (wControl_p)wComboListCreate( win, xx, yy, helpStr, _(pd->winLabel), pd->winOption, listDataP->number, listDataP->width, NULL, ParamListPush, pd ); + listDataP->height = wControlGetHeight( pd->control ); + break; + case PD_COLORLIST: + pd->control = (wControl_p)wColorSelectButtonCreate( win, xx, yy, helpStr, _(pd->winLabel), pd->winOption, 0, &color, ParamColorSelectPush, pd ); + break; + case PD_MESSAGE: + if ( pd->winData != 0 ) + w = (wPos_t)(long)pd->winData; + else if (pd->valueP) + w = wLabelWidth( _(pd->valueP) ); + else + w = 150; + pd->control = (wControl_p)wMessageCreateEx( win, xx, yy, _(pd->winLabel), w, pd->valueP?_(pd->valueP):" ", pd->winOption ); + break; + case PD_BUTTON: + pd->control = (wControl_p)wButtonCreate( win, xx, yy, helpStr, _(pd->winLabel), pd->winOption, 0, ParamButtonPush, pd ); + break; + case PD_MENU: + menu = wMenuCreate( win, xx, yy, helpStr, _(pd->winLabel), pd->winOption ); + pd->control = (wControl_p)menu; + break; + case PD_MENUITEM: + pd->control = (wControl_p)wMenuPushCreate( menu, helpStr, _(pd->winLabel), 0, ParamMenuPush, pd ); + break; + case PD_DRAW: + drawDataP = pd->winData; + pd->control = (wControl_p)wDrawCreate( win, xx, yy, helpStr, pd->winOption, drawDataP->width, drawDataP->height, pd, ParamDrawRedraw, ParamDrawAction ); + if ( drawDataP->d ) { + drawDataP->d->d = (wDraw_p)pd->control; + drawDataP->d->dpi = wDrawGetDPI( drawDataP->d->d ); + } + break; + case PD_TEXT: + textDataP = pd->winData; + pd->control = (wControl_p)wTextCreate( win, xx, yy, helpStr, NULL, pd->winOption, textDataP->width, textDataP->height ); + if ( (pd->winOption&BO_READONLY) == 0 ) + wTextSetReadonly( (wText_p)pd->control, FALSE ); + break; + case PD_BITMAP: + iconP = pd->winData; + pd->control = (wControl_p)wBitmapCreate( win, xx, yy, pd->winOption, iconP ); + break; + default: + AbortProg( "paramCreatePG" ); + } + +} + + +static void ParamPositionControl( + paramData_p pd, + char * helpStr, + wPos_t xx, + wPos_t yy ) +{ + paramDrawData_t * drawDataP; + paramTextData_t * textDataP; + paramListData_t * listDataP; + wPos_t winW, winH, ctlW, ctlH; + + if ( pd->type != PD_MENUITEM ) + wControlSetPos( pd->control, xx, yy ); + if ( pd->option&PDO_DLGRESIZE ) { + wWinGetSize( pd->group->win, &winW, &winH ); + switch (pd->type) { + case PD_LIST: + case PD_COMBOLIST: + case PD_DROPLIST: + if ( pd->type == PD_DROPLIST ) { + ctlW = pd->winData?(wPos_t)(long)pd->winData:(wPos_t)100; + ctlH = wControlGetHeight( pd->control ); + } else { + listDataP = (paramListData_t*)pd->winData; + ctlW = listDataP->width; + ctlH = listDataP->height; + } + if ( (pd->option&PDO_DLGRESIZE) == 0 ) + break; + if ( (pd->option&PDO_DLGRESIZEW) != 0 ) + ctlW = winW - (pd->group->origW-ctlW); + if ( (pd->option&PDO_DLGRESIZEH) != 0 ) + ctlH = winH - (pd->group->origH-ctlH); + wListSetSize( (wList_p)pd->control, ctlW, ctlH ); + break; + case PD_DRAW: + drawDataP = pd->winData; + if ( (pd->option&PDO_DLGRESIZEW) ) + ctlW = winW - (pd->group->origW-drawDataP->width); + else + ctlW = wControlGetWidth( pd->control ); + if ( (pd->option&PDO_DLGRESIZEH) ) + ctlH = winH - (pd->group->origH-drawDataP->height); + else + ctlH = wControlGetHeight( pd->control ); + wDrawSetSize( (wDraw_p)pd->control, ctlW, ctlH ); + if ( drawDataP->redraw ) + drawDataP->redraw( (wDraw_p)pd->control, pd->context, ctlW, ctlH ); + break; + case PD_TEXT: + textDataP = pd->winData; + ctlW = textDataP->width; + ctlH = textDataP->height; + if ( (pd->winOption&BT_CHARUNITS) ) + wTextComputeSize( (wText_p)pd->control, ctlW, ctlH, &ctlW, &ctlH ); + if ( (pd->option&PDO_DLGRESIZEW) ) + ctlW = winW - (pd->group->origW-ctlW); + else + ctlW = wControlGetWidth( pd->control ); + if ( (pd->option&PDO_DLGRESIZEH) ) + ctlH = winH - (pd->group->origH-ctlH); + else + ctlH = wControlGetHeight( pd->control ); + wTextSetSize( (wText_p)pd->control, ctlW, ctlH ); + break; + case PD_STRING: + ctlW = pd->winData?(wPos_t)(long)pd->winData:(wPos_t)250; + if ( (pd->option&PDO_DLGRESIZEW) ) { + ctlW = winW - (pd->group->origW-ctlW); + wStringSetWidth( (wString_p)pd->control, ctlW ); + } + break; + case PD_MESSAGE: + ctlW = pd->winData?(wPos_t)(long)pd->winData:(wPos_t)150; + if ( (pd->option&PDO_DLGRESIZEW) ) { + ctlW = winW - (pd->group->origW-ctlW); + wMessageSetWidth( (wMessage_p)pd->control, ctlW ); + } + break; + default: + AbortProg( "paramPositionControl" ); + } + } +} + + +typedef void (*layoutControlsProc)(paramData_p, char *, wPos_t, wPos_t ); +static void LayoutControls( + paramGroup_p group, + layoutControlsProc proc, + wPos_t * retW, + wPos_t * retH ) +{ + struct { + struct { wPos_t x, y; } orig, term; + } controlK, columnK, windowK; + wPos_t controlSize_x; + wPos_t controlSize_y; + paramData_p pd; + wPos_t w; + BOOL_T hasBox; + wPos_t boxTop; + wPos_t boxPos[10]; + int boxCnt = 0; + int box; + int inx; + wPos_t labelW[100]; + int lastLabelPos, currLabelPos; + char helpStr[STR_SHORT_SIZE], * helpStrP; + BOOL_T inCmdButtons = FALSE; + wButton_p lastB = NULL; + BOOL_T areCmdButtons = FALSE; + + strcpy( helpStr, group->nameStr ); + helpStrP = helpStr+strlen(helpStr); + *helpStrP++ = '-'; + *helpStrP = 0; + controlK.orig.x = 0; + hasBox = FALSE; + memset( boxPos, 0, sizeof boxPos ); + memset( labelW, 0, sizeof labelW ); + lastLabelPos = 0; + currLabelPos = 0; + for ( pd=group->paramPtr; pd<&group->paramPtr[group->paramCnt]; pd++,currLabelPos++ ) { + if ( (pd->option&PDO_DLGIGNORE) != 0 ) + continue; + if ( (pd->option&PDO_DLGBOXEND) ) + hasBox = TRUE; + if ( (pd->option&(PDO_DLGRESETMARGIN|PDO_DLGNEWCOLUMN|PDO_DLGCMDBUTTON)) ) { + for ( inx=lastLabelPos; inx<currLabelPos; inx++ ) + labelW[inx] = controlK.orig.x; + controlK.orig.x = 0; + lastLabelPos = currLabelPos; + } + if ( pd->winLabel && (pd->option&(PDO_DLGIGNORELABELWIDTH|PDO_DLGHORZ))==0 && + pd->type!=PD_BUTTON && + pd->type!=PD_MENU && + pd->type!=PD_MENUITEM) { + w = wLabelWidth( _(pd->winLabel) ); + if ( w > controlK.orig.x ) + controlK.orig.x = w; + } + } + for ( inx=lastLabelPos; inx<group->paramCnt; inx++ ) + labelW[inx] = controlK.orig.x; + for ( inx=0; inx<group->paramCnt; inx++ ) + if ( (group->paramPtr[inx].option&PDO_DLGNOLABELALIGN) != 0 ) + labelW[inx] = 0; + + LOG( log_paramLayout, 1, ("Layout %s B?=%s\n", group->nameStr, hasBox?"T":"F" ) ) + + windowK.orig.x = DlgSepLeft + (hasBox?DlgSepFrmLeft:0); + windowK.orig.y = DlgSepTop + (hasBox?DlgSepFrmTop:0); + windowK.term = windowK.orig; + controlK = columnK = windowK; + controlK.orig.x += labelW[0]; + + for ( pd = group->paramPtr,inx=0; pd<&group->paramPtr[group->paramCnt]; pd++,inx++ ) { + LOG( log_paramLayout, 1, ("%2d: Col %dx%d..%dx%d Ctl %dx%d..%dx%d\n", inx, + columnK.orig.x, columnK.orig.y, columnK.term.x, columnK.term.y, + controlK.orig.x, controlK.orig.y, controlK.term.x, controlK.term.y ) ) + if ( (pd->option&PDO_DLGIGNORE) != 0 ) + goto SkipControl; + if ( pd->type == PD_MENUITEM ) { + proc( pd, helpStr, 0, 0 ); + continue; + } + /* + * Set control orig + */ + if ( (pd->option&PDO_DLGNEWCOLUMN) ) { + columnK.orig.x = columnK.term.x; + columnK.orig.x += ((pd->option&PDO_DLGWIDE)?10:DlgSepNarrow); + columnK.term.y = columnK.orig.y; + controlK.orig.x = columnK.orig.x + labelW[inx]; + controlK.orig.y = columnK.orig.y; + } else if ( (pd->option&PDO_DLGHORZ) ) { + controlK.orig.x = controlK.term.x; + if ( (pd->option&PDO_DLGWIDE) ) + controlK.orig.x += 10; + else if ( (pd->option&PDO_DLGNARROW)== 0) + controlK.orig.x += 3; + if ( pd->winLabel && ( pd->type!=PD_BUTTON ) ) + controlK.orig.x += wLabelWidth( _(pd->winLabel) ); + } else if ( inx != 0 ) { + controlK.orig.x = columnK.orig.x + labelW[inx]; + controlK.orig.y = controlK.term.y; + if ( (pd->option&PDO_DLGWIDE) ) + controlK.orig.y += 10; + else if ( (pd->option&PDO_DLGNARROW)== 0) + controlK.orig.y += 3; + } + if ( (pd->option&PDO_DLGSETY) ) { + columnK.term.x = controlK.orig.x; + columnK.orig.y = controlK.orig.y; + } + /* + * Custom layout and create/postion control + */ + if (group->layoutProc) + group->layoutProc( pd, inx, columnK.orig.x+labelW[inx], &controlK.orig.x, &controlK.orig.y ); + if ( pd->nameStr ) + strcpy( helpStrP, pd->nameStr ); + proc( pd, helpStr, controlK.orig.x, controlK.orig.y ); + /* + * Set control term + */ + controlSize_x = wControlGetWidth( pd->control ); + controlSize_y = wControlGetHeight( pd->control ); + controlK.term.x = controlK.orig.x+controlSize_x; + if ( (pd->option&PDO_DLGHORZ)==0 || + controlK.term.y < controlK.orig.y+controlSize_y ) + controlK.term.y = controlK.orig.y+controlSize_y; + if ( retW && pd->nameStr ) { + char * cp; + strcpy( message, pd->nameStr ); + for ( cp=message; *cp; cp++ ) if ( *cp == '-' ) *cp = '_'; + LOG( log_hotspot, 1, ( "popup %d %d %d %d _%s_%s\n", + controlK.orig.x+hotspotOffsetX, controlK.orig.y+hotspotOffsetY, + controlSize_x, controlSize_y, + group->nameStr, message ) ) + } + /* + * Set column term + */ + if ( (pd->option&PDO_DLGIGNOREX) == 0 ) { + if ( (pd->option&PDO_DLGUNDERCMDBUTT) == 0 ) { + if ( columnK.term.x < controlK.term.x ) + columnK.term.x = controlK.term.x; + } else { + if ( columnK.term.x < controlK.term.x-90 ) + columnK.term.x = controlK.term.x-90; + } + } + if ( columnK.term.y < controlK.term.y ) + columnK.term.y = controlK.term.y; + if ( hasBox ) + if ( boxPos[boxCnt] < columnK.term.y+2 ) + boxPos[boxCnt] = columnK.term.y+2; + if ( (pd->option&PDO_DLGBOXEND) ) { + columnK.term.y += 8; + boxCnt++; + controlK.term.y = columnK.term.y; + } + /* + * Set window term + */ + if ( windowK.term.x < columnK.term.x ) + windowK.term.x = columnK.term.x; + if ( windowK.term.y < columnK.term.y ) + windowK.term.y = columnK.term.y; + if ( (pd[1].option&PDO_DLGCMDBUTTON) ) + areCmdButtons = TRUE; +SkipControl: + if ( (!inCmdButtons) && + (pd==&group->paramPtr[group->paramCnt-1] || (pd[1].option&PDO_DLGCMDBUTTON)) ) { + columnK.orig.x = columnK.term.x + DlgSepMid; + if ( boxCnt ) { + boxTop = DlgSepTop; + if ( group->boxs == NULL ) { + group->boxs = (wBox_p*)MyMalloc( boxCnt * sizeof *(wBox_p*)0 ); + for ( box=0; box<boxCnt; box++ ) { + group->boxs[box] = wBoxCreate( group->win, DlgSepLeft, boxTop, NULL, wBoxBelow, columnK.term.x, boxPos[box]-boxTop ); + boxTop = boxPos[box] + 4; + } + } else { + for ( box=0; box<boxCnt; box++ ) { + wControlSetPos( (wControl_p)group->boxs[box], DlgSepLeft, boxTop ); + wBoxSetSize( group->boxs[box], columnK.term.x, boxPos[box]-boxTop ); + boxTop = boxPos[box] + 4; + } + } + columnK.orig.x += DlgSepFrmRight; + } + columnK.orig.y = columnK.term.y = DlgSepTop; + controlK = columnK; + if ( group->okB ) { + wControlSetPos( (wControl_p)(lastB=group->okB), columnK.orig.x, columnK.orig.y ); + controlK.term.y += wControlGetHeight((wControl_p)group->okB); + columnK.term.y = controlK.term.y + 3; + } + inCmdButtons = TRUE; + } + LOG( log_paramLayout, 1, (" Col %dx%d..%dx%d Ctl %dx%d..%dx%d\n", + columnK.orig.x, columnK.orig.y, columnK.term.x, columnK.term.y, + controlK.orig.x, controlK.orig.y, controlK.term.x, controlK.term.y ) ) + if ( windowK.term.x < columnK.term.x ) + windowK.term.x = columnK.term.x; + if ( windowK.term.y < columnK.term.y ) + windowK.term.y = columnK.term.y; + } + if ( group->cancelB ) { + if ( areCmdButtons ) + columnK.term.y += 10; + else if ( group->okB ) + columnK.term.y += 3; + wControlSetPos( (wControl_p)(lastB=group->cancelB), columnK.orig.x, columnK.term.y ); + columnK.term.y += wControlGetHeight((wControl_p)group->cancelB); + } + if ( group->helpB ) { + columnK.term.y += 10; + wControlSetPos( (wControl_p)(lastB=group->helpB), columnK.orig.x, columnK.term.y ); + columnK.term.y += wControlGetHeight((wControl_p)group->helpB); + } + if ( lastB ) { + controlK.term.x = controlK.orig.x + wControlGetWidth((wControl_p)lastB); + if ( columnK.term.x < controlK.term.x ) + columnK.term.x = controlK.term.x; + } + if ( windowK.term.x < columnK.term.x ) + windowK.term.x = columnK.term.x; + if ( windowK.term.y < columnK.term.y ) + windowK.term.y = columnK.term.y; + + if ( retW ) + *retW = windowK.term.x; + if ( retH ) + *retH = windowK.term.y; +} + + +static void ParamDlgProc( + wWin_p win, + winProcEvent e, + void * data ) +{ + paramGroup_p pg = (paramGroup_p)data; + switch (e) { + case wClose_e: + if ( pg->changeProc ) + pg->changeProc( pg, -1, NULL ); + if ( (pg->options&PGO_NODEFAULTPROC) == 0 ) + DefaultProc( win, wClose_e, data ); + break; + case wResize_e: + LayoutControls( pg, ParamPositionControl, NULL, NULL ); + break; + default: + break; + } +} + + + +EXPORT wWin_p ParamCreateDialog( + paramGroup_p group, + char * title, + char * okLabel, + paramActionOkProc okProc, + paramActionCancelProc cancelProc, + BOOL_T needHelpButton, + paramLayoutProc layoutProc, + long winOption, + paramChangeProc changeProc ) +{ + char helpStr[STR_SHORT_SIZE]; + wPos_t w0, h0; + wButton_p lastB = NULL; + char * cancelLabel = (winOption&PD_F_ALT_CANCELLABEL?_("Close"):_("Cancel")); + + winOption &= ~PD_F_ALT_CANCELLABEL; + group->okProc = okProc; + group->cancelProc = cancelProc; + group->layoutProc = layoutProc; + group->changeProc = changeProc; + if ( (winOption&F_CENTER) == 0 ) + winOption |= F_RECALLPOS; + if ( (winOption&F_RESIZE) != 0 ) + winOption |= F_RECALLSIZE; + + sprintf( helpStr, "cmd%s", group->nameStr ); + helpStr[3] = toupper(helpStr[3]); + + group->win = wWinPopupCreate( mainW, DlgSepRight, DlgSepFrmBottom, helpStr, title, group->nameStr, F_AUTOSIZE|winOption, ParamDlgProc, group ); + + if ( okLabel && okProc ) { + sprintf( helpStr, "%s-ok", group->nameStr ); + lastB = group->okB = wButtonCreate( group->win, 0, 0, helpStr, okLabel, BB_DEFAULT, 0, (wButtonCallBack_p)ParamButtonOk, group ); + } + if ( group->cancelProc ) { + lastB = group->cancelB = wButtonCreate( group->win, 0, 0, NULL, cancelLabel, BB_CANCEL, 0, (wButtonCallBack_p)ParamButtonCancel, group ); + } + if ( needHelpButton ) { + sprintf( helpStr, "cmd%s", group->nameStr ); + helpStr[3] = toupper(helpStr[3]); + lastB = group->helpB = wButtonCreate( group->win, 0, 0, NULL, _("Help"), BB_HELP, 0, (wButtonCallBack_p)wHelp, MyStrdup(helpStr) ); + } + + LOG( log_hotspot, 1, ( "mkshg ${PNG2DIR}/%s.png ${SHGDIR}/%s.shg << EOF\n", group->nameStr, group->nameStr ) ) + LayoutControls( group, ParamCreateControl, &group->origW, &group->origH ); + if ( group->okB ) + LOG( log_hotspot, 1, ( "popup %d %d %d %d _%s_%s\n", + wControlGetPosX((wControl_p)(group->okB))+hotspotOffsetX, + wControlGetPosY((wControl_p)(group->okB))+hotspotOffsetY, + wControlGetWidth((wControl_p)(group->okB)), + wControlGetHeight((wControl_p)(group->okB)), + group->nameStr, "ok" ) ) + LOG( log_hotspot, 1, ( "EOF\n" ) ) + + group->origW += DlgSepRight; + group->origH += DlgSepBottom; + wWinGetSize( group->win, &w0, &h0 ); + if ( (winOption&F_RESIZE) ) { + if ( group->origW != w0 || + group->origH != h0 ) { + LayoutControls( group, ParamPositionControl, NULL, NULL ); + } + } else if ( group->origW > w0 || group->origH > h0 ) { + if ( group->origW > w0 ) + w0 = group->origW; + if ( group->origH > h0 ) + h0 = group->origH; + wWinSetSize( group->win, w0, h0 ); + } + + return group->win; +} + + +/** Resize dialog window for the contained fields. +* \param IN OUT Prameter Group +* +*/ +EXPORT void ParamLayoutDialog( + paramGroup_p pg ) +{ + wPos_t w, h; + LayoutControls( pg, ParamPositionControl, &w, &h ); + w += DlgSepRight; + h += DlgSepBottom; + if ( w != pg->origW || h != pg->origH ) { + wWinSetSize( pg->win, w, h ); + pg->origW = w; + pg->origH = h; + } +} + + +EXPORT void ParamDialogOkActive( + paramGroup_p pg, + int active ) +{ + if ( pg->okB ) + wControlActive( (wControl_p)pg->okB, active ); +} + + +EXPORT void ParamCreateControls( + paramGroup_p pg, + paramChangeProc changeProc ) +{ + paramData_p pd; + char helpStr[STR_SHORT_SIZE], * helpStrP; + strcpy( helpStr, pg->nameStr ); + helpStrP = helpStr+strlen(helpStr); + *helpStrP++ = '-'; + for ( pd=pg->paramPtr; pd<&pg->paramPtr[pg->paramCnt]; pd++ ) { + pd->group = pg; + strcpy( helpStrP, pd->nameStr ); + ParamCreateControl( pd, helpStr, 0, 0 ); + if ( pd->type != PD_MENUITEM && pd->control ) + wControlShow( pd->control, FALSE ); + } + pg->changeProc = changeProc; +} + + +EXPORT void ParamInit( void ) +{ + AddPlaybackProc( "PARAMETER", ParamPlayback, NULL ); + AddPlaybackProc( "PARAMCHECK", ParamCheck, NULL ); + log_hotspot = LogFindIndex( "hotspot" ); + log_paramLayout = LogFindIndex( "paramlayout" ); +} |