summaryrefslogtreecommitdiff
path: root/app/bin/celev.c
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2016-12-28 16:52:56 +0100
committerJörg Frings-Fürst <debian@jff-webhosting.net>2016-12-28 16:52:56 +0100
commit7b358424ebad9349421acd533c2fa1cbf6cf3e3e (patch)
tree686678532eefed525c242fd214d0cfb2914726c5 /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.c475
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 );
+}
+