diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2016-12-28 16:52:56 +0100 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2016-12-28 16:52:56 +0100 |
commit | 7b358424ebad9349421acd533c2fa1cbf6cf3e3e (patch) | |
tree | 686678532eefed525c242fd214d0cfb2914726c5 /app/bin/celev.c |
Initial import of xtrkcad version 1:4.0.2-2
Diffstat (limited to 'app/bin/celev.c')
-rw-r--r-- | app/bin/celev.c | 475 |
1 files changed, 475 insertions, 0 deletions
diff --git a/app/bin/celev.c b/app/bin/celev.c new file mode 100644 index 0000000..b4691d1 --- /dev/null +++ b/app/bin/celev.c @@ -0,0 +1,475 @@ +/* + * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/bin/celev.c,v 1.4 2008-03-06 19:35:05 m_fischer Exp $ + */ + +/* 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 "track.h" +#include "cselect.h" +#include "i18n.h" + +/***************************************************************************** + * + * ELEVATION + * + */ + +static wWin_p elevW; + +static long elevModeV; +static char elevStationV[STR_SIZE]; +static DIST_T elevHeightV = 0.0; + +static DIST_T elevOldValue; +static track_p elevTrk; +static EPINX_T elevEp; +static BOOL_T elevUndo = FALSE; + +static char * elevModeLabels[] = { N_("None"), N_("Defined"), N_("Hidden"), + N_("Computed"), N_("Grade"), N_("Station"), N_("Ignore"), NULL }; +static paramFloatRange_t r_1000_1000 = { -1000, 1000 }; + +static paramData_t elevationPLs[] = { +#define I_MODE (0) + { PD_RADIO, &elevModeV, "mode", 0, elevModeLabels, "" }, +#define I_HEIGHT (1) + { PD_FLOAT, &elevHeightV, "value", PDO_DIM|PDO_DLGNEWCOLUMN, &r_1000_1000 }, +#define I_COMPUTED (2) + { PD_MESSAGE, NULL, "computed", 0, (void*)80 }, +#define I_GRADE (3) + { PD_MESSAGE, NULL, "grade", 0, (void*)80 }, +#define I_STATION (4) + { PD_STRING, elevStationV, "station", PDO_DLGUNDERCMDBUTT, (void*)200 } }; +static paramGroup_t elevationPG = { "elev", 0, elevationPLs, sizeof elevationPLs/sizeof elevationPLs[0] }; + + +static void LayoutElevW( + paramData_t * pd, + int inx, + wPos_t colX, + wPos_t * x, + wPos_t * y ) +{ + static wPos_t h = 0; + switch ( inx ) { + case I_HEIGHT: + h = wControlGetHeight( elevationPLs[I_MODE].control )/((sizeof elevModeLabels/sizeof elevModeLabels[0])-1); +#ifndef WINDOWS + h += 3; +#endif + *y = DlgSepTop+h+h/2; + break; + case I_COMPUTED: + case I_GRADE: + case I_STATION: + *y = DlgSepTop+h*(inx+1); + break; + } +} + + +static int GetElevMode( void ) +{ + int mode; + int newMode; + static int modeMap[7] = { ELEV_NONE, ELEV_DEF|ELEV_VISIBLE, ELEV_DEF, ELEV_COMP|ELEV_VISIBLE, ELEV_GRADE|ELEV_VISIBLE, ELEV_STATION|ELEV_VISIBLE, ELEV_IGNORE }; + mode = (int)elevModeV; + if (mode<0||mode>=7) + return -1; + newMode = modeMap[mode]; + return newMode; +} + + +#ifdef LATER +static void DoElevRadio( long mode, void * context ) +{ + if ( mode < 0 || mode >= 7 ) + return; +#ifdef ELEVM + ParamLoadMessage( elevMessageM, "" ); +#endif + ParamControlActive( &elevationPG, I_HEIGHT, FALSE ); + ParamControlActive( &elevationPG, I_STATION, FALSE ); + switch ( mode ) { + case 0: + break; + case 1: + case 2: + ParamControlActive( &elevationPG, I_HEIGHT, TRUE ); + break; + case 3: + case 4: +#ifdef OLDELEV + if ( !( (rc0 == FDE_DEF && rc1 == FDE_DEF) || + (rc0 == FDE_DEF && rc1 == FDE_END) || + (rc0 == FDE_END && rc1 == FDE_DEF) ) ) { + ParamLoadMessage( &elevationPG, I_MSG, _("There are no reachable Defined Elevations") ); + ParamLoadControl( &elevationPG, I_MODE ); + return; + } +#endif + break; + case 5: + wControlActive( (wControl_p)elevStationS, TRUE ); + break; + } + elevModeV = mode; + DoElevUpdate( NULL, 1, NULL ); +} +#endif + + +static void DoElevUpdate( paramGroup_p pg, int inx, void * valueP ) +{ + int oldMode, newMode; + coOrd pos; + DIST_T elevNewValue, elevOldValue, diff; + DIST_T radius; + + if ( inx == 0 ) { + long mode = *(long*)valueP; + if ( mode < 0 || mode >= 7 ) + return; +#ifdef ELEVM + ParamLoadMessage( elevMessageM, "" ); +#endif + ParamControlActive( &elevationPG, I_HEIGHT, FALSE ); + ParamControlActive( &elevationPG, I_STATION, FALSE ); + switch ( mode ) { + case 0: + break; + case 1: + case 2: + ParamControlActive( &elevationPG, I_HEIGHT, TRUE ); + break; + case 3: + case 4: +#ifdef OLDELEV + if ( !( (rc0 == FDE_DEF && rc1 == FDE_DEF) || + (rc0 == FDE_DEF && rc1 == FDE_END) || + (rc0 == FDE_END && rc1 == FDE_DEF) ) ) { + ParamLoadMessage( &elevationPG, I_MSG, _("There are no reachable Defined Elevations") ); + ParamLoadControl( &elevationPG, I_MODE ); + return; + } +#endif + break; + case 5: + ParamControlActive( &elevationPG, I_STATION, TRUE ); + break; + } + elevModeV = mode; + } + ParamLoadData( &elevationPG ); + newMode = GetElevMode(); + if (newMode == -1) + return; + if (elevTrk == NULL) + return; + oldMode = GetTrkEndElevUnmaskedMode( elevTrk, elevEp ); + elevNewValue = 0.0; + if ((newMode&ELEV_MASK) == ELEV_DEF) + elevNewValue = elevHeightV; + if (oldMode == newMode) { + if ((newMode&ELEV_MASK) == ELEV_DEF) { + elevOldValue = GetTrkEndElevHeight( elevTrk, elevEp ); + diff = fabs( elevOldValue-elevNewValue ); + if ( diff < 0.02 ) + return; + } else if ((newMode&ELEV_MASK) == ELEV_STATION) { + if ( strcmp(elevStationV, GetTrkEndElevStation( elevTrk, elevEp ) ) == 0) + return; + } else { + return; + } + } + if (elevUndo == FALSE) { + UndoStart( _("Set Elevation"), "Set Elevation" ); + elevUndo = TRUE; + } + pos = GetTrkEndPos( elevTrk, elevEp ); + radius = 0.05*mainD.scale; + if ( radius < trackGauge/2.0 ) + radius = trackGauge/2.0; + if ( (oldMode&ELEV_MASK)==ELEV_DEF || (oldMode&ELEV_MASK)==ELEV_IGNORE ) + DrawFillCircle( &tempD, pos, radius, + ((oldMode&ELEV_MASK)==ELEV_DEF?elevColorDefined:elevColorIgnore)); + HilightSelectedEndPt(FALSE, elevTrk, elevEp); + UpdateTrkEndElev( elevTrk, elevEp, newMode, elevNewValue, elevStationV ); + HilightSelectedEndPt(TRUE, elevTrk, elevEp); + if ( (newMode&ELEV_MASK)==ELEV_DEF || (newMode&ELEV_MASK)==ELEV_IGNORE ) + DrawFillCircle( &tempD, pos, radius, + ((newMode&ELEV_MASK)==ELEV_DEF?elevColorDefined:elevColorIgnore)); +} + + +static void DoElevDone( void * arg ) +{ + DoElevUpdate( NULL, 1, NULL ); + HilightElevations( FALSE ); + HilightSelectedEndPt( FALSE, elevTrk, elevEp ); + wHide( elevW ); + elevTrk = NULL; + Reset(); +} + + +static void DoElevHilight( void * junk ) +{ + HilightElevations( TRUE ); +} + + +static void ElevSelect( track_p trk, EPINX_T ep ) +{ + int mode; + DIST_T elevX, grade, elev, dist; + long radio; + BOOL_T computedOk; + BOOL_T gradeOk = TRUE; + track_p trk1; + EPINX_T ep1; + + DoElevUpdate( NULL, 1, NULL ); + elevOldValue = 0.0; + elevHeightV = 0.0; + elevStationV[0] = 0; + HilightSelectedEndPt(FALSE, elevTrk, elevEp); + elevTrk = trk; + elevEp = ep; + mode = GetTrkEndElevUnmaskedMode( trk, ep ); + ParamLoadControls( &elevationPG ); + ParamControlActive( &elevationPG, I_MODE, TRUE ); + ParamControlActive( &elevationPG, I_HEIGHT, FALSE ); + ParamControlActive( &elevationPG, I_STATION, FALSE ); + ParamLoadMessage( &elevationPG, I_COMPUTED, "" ); + ParamLoadMessage( &elevationPG, I_GRADE, "" ); + switch (mode & ELEV_MASK) { + case ELEV_NONE: + radio = 0; + break; + case ELEV_DEF: + if ( mode & ELEV_VISIBLE ) + radio = 1; + else + radio = 2; + elevHeightV = GetTrkEndElevHeight(trk,ep); + elevOldValue = elevHeightV; + ParamLoadControl( &elevationPG, I_HEIGHT ); + ParamControlActive( &elevationPG, I_HEIGHT, TRUE ); + break; + case ELEV_COMP: + radio = 3; + break; + case ELEV_GRADE: + radio = 4; + break; + case ELEV_STATION: + radio = 5; + strcpy( elevStationV, GetTrkEndElevStation(trk,ep) ); + ParamLoadControl( &elevationPG, I_STATION ); + ParamControlActive( &elevationPG, I_STATION, TRUE ); + break; + case ELEV_IGNORE: + radio = 6; + break; + default: + radio = 0; + } + elevModeV = radio; + ParamLoadControl( &elevationPG, I_MODE ); +#ifdef OLDELEV +if (oldElevationEvaluation) { + int dir; + ANGLE_T a; + int rc0, rc1; + DIST_T elev0, elev1, dist0, dist1; + a = GetTrkEndAngle( trk, ep ); + dir = ( a > 270 || a < 90 ); + rc0 = FindDefinedElev( trk, ep, dir, FALSE, &elev0, &dist0 ); + rc1 = FindDefinedElev( trk, ep, 1-dir, FALSE, &elev1, &dist1 ); + if ( rc0 == FDE_DEF ) { + sprintf( message, _("Elev = %s"), FormatDistance(elev0) ); + ParamLoadMessage( elev1ElevM, message ); + sprintf( message, _("Dist = %s"), FormatDistance(dist0) ); + ParamLoadMessage( elev1DistM, message ); +#ifdef LATER + if (dist0 > 0.1) + sprintf( message, "%0.1f%%", elev0/dist0 ); + else + sprintf( message, _("Undefined") ); + ParamLoadMessage( elev1GradeM, message ); +#endif + } else { + ParamLoadMessage( elev1ElevM, "" ); + ParamLoadMessage( elev1DistM, "" ); + /*ParamLoadMessage( elev1GradeM, "" );*/ + } + if ( rc1 == FDE_DEF ) { + sprintf( message, _("Elev = %s"), FormatDistance(elev1) ); + ParamLoadMessage( elev2ElevM, message ); + sprintf( message, _("Dist = %s"), FormatDistance(dist1) ); + ParamLoadMessage( elev2DistM, message ); +#ifdef LATER + if (dist1 > 0.1) + sprintf( message, "%0.1f%%", elev1/dist1 ); + else + sprintf( message, _("Undefined") ); + ParamLoadMessage( elev2GradeM, message ); +#endif + } else { + ParamLoadMessage( elev2ElevM, "" ); + ParamLoadMessage( elev2DistM, "" ); + /*ParamLoadMessage( elev2GradeM, "" );*/ + } + computedOk = TRUE; + if (rc0 == FDE_DEF && rc1 == FDE_DEF) { + grade = (elev1-elev0)/(dist0+dist1); + elevX = elev0 + grade*dist0; + } else if (rc0 == FDE_DEF && rc1 == FDE_END) { + grade = 0.0; + elevX = elev0; + } else if (rc0 == FDE_END && rc1 == FDE_DEF) { + elevX = elev1; + grade = 0.0; + } else { + gradeOk = FALSE; + computedOk = FALSE; + } +} else { +#endif + gradeOk = ComputeElev( trk, ep, FALSE, &elevX, &grade ); + computedOk = TRUE; +#ifdef OLDELEV +} +#endif + if (oldElevationEvaluation || computedOk) { + sprintf( message, "%0.2f%s", PutDim( elevX ), (units==UNITS_METRIC?"cm":"\"") ); + ParamLoadMessage( &elevationPG, I_COMPUTED, message ); + if (gradeOk) { + sprintf( message, "%0.1f%%", fabs(grade*100) ); + } else { + if ( EndPtIsDefinedElev(trk,ep) ) { + elev = GetElevation(trk); + dist = GetTrkLength(trk,ep,-1); + if (dist>0.1) + sprintf( message, "%0.1f%%", fabs((elev-elevX)/dist)*100.0 ); + else + sprintf( message, _("Undefined") ); + if ( (trk1=GetTrkEndTrk(trk,ep)) && (ep1=GetEndPtConnectedToMe(trk1,trk))>=0 ) { + elev = GetElevation(trk1); + dist = GetTrkLength(trk1,ep1,-1); + if (dist>0.1) + sprintf( message+strlen(message), " - %0.1f%%", fabs((elev-elevX)/dist)*100.0 ); + else + sprintf( message+strlen(message), " - %s", _("Undefined") ); + } + } else { + strcpy( message, _("Undefined") ); + } + } + ParamLoadMessage( &elevationPG, I_GRADE, message ); + if ( (mode&ELEV_MASK)!=ELEV_DEF ) { + elevHeightV = elevX; + ParamLoadControl( &elevationPG, I_HEIGHT ); + } + } + HilightSelectedEndPt(TRUE, elevTrk, elevEp); +} + + +static STATUS_T CmdElevation( wAction_t action, coOrd pos ) +{ + track_p trk0, trk1; + EPINX_T ep0; + int oldTrackCount; + + switch (action) { + case C_START: + if ( elevW == NULL ) + elevW = ParamCreateDialog( &elevationPG, MakeWindowTitle(_("Elevation")), _("Done"), DoElevDone, NULL, TRUE, LayoutElevW, 0, DoElevUpdate ); + elevModeV = 0; + elevHeightV = 0.0; + elevStationV[0] = 0; + ParamLoadControls( &elevationPG ); + ParamGroupRecord( &elevationPG ); + wShow( elevW ); + ParamControlActive( &elevationPG, I_MODE, FALSE ); + ParamControlActive( &elevationPG, I_HEIGHT, FALSE ); + ParamControlActive( &elevationPG, I_STATION, FALSE ); + ParamLoadMessage( &elevationPG, I_COMPUTED, "" ); + ParamLoadMessage( &elevationPG, I_GRADE, "" ); + InfoMessage( _("Select End-Point") ); + HilightElevations( TRUE ); + elevTrk = NULL; + elevUndo = FALSE; + return C_CONTINUE; + case C_RDOWN: + case C_RMOVE: + case C_RUP: + CmdMoveDescription( action-C_RDOWN+C_DOWN, pos ); + return C_CONTINUE; + case C_LCLICK: + if ((trk0 = OnTrack( &pos, TRUE, TRUE )) == NULL) { + return C_CONTINUE; + } + if ( (MyGetKeyState()&WKEY_SHIFT) ) { + ep0 = PickEndPoint( pos, trk0 ); + UndoStart( _("Split Track"), "SplitTrack( T%d[%d] )", GetTrkIndex(trk0), ep0 ); + oldTrackCount = trackCount; + if (!SplitTrack( trk0, pos, ep0, &trk1, FALSE )) + return C_CONTINUE; + ElevSelect( trk0, ep0 ); + UndoEnd(); + elevUndo = FALSE; + } else { + ep0 = PickEndPoint( pos, trk0 ); + ElevSelect( trk0, ep0 ); + return C_CONTINUE; + } + return C_CONTINUE; + case C_OK: + DoElevDone(NULL); + return C_TERMINATE; + case C_CANCEL: + HilightElevations( FALSE ); + HilightSelectedEndPt( FALSE, elevTrk, elevEp ); + elevTrk = NULL; + wHide( elevW ); + return C_TERMINATE; + case C_REDRAW: + DoElevHilight( NULL ); + HilightSelectedEndPt( TRUE, elevTrk, elevEp ); + return C_CONTINUE; + } + return C_CONTINUE; +} + + + + +#include "bitmaps/elev.xpm" + +EXPORT void InitCmdElevation( wMenu_p menu ) +{ + ParamRegister( &elevationPG ); + AddMenuButton( menu, CmdElevation, "cmdElevation", _("Elevation"), wIconCreatePixMap(elev_xpm), LEVEL0_50, IC_POPUP|IC_LCLICK, ACCL_ELEVATION, NULL ); +} + |