/** \file cparalle.c * PARALLEL */ /* 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 #include "ccurve.h" #include "cstraigh.h" #include "cundo.h" #include "i18n.h" #include "messages.h" #include "param.h" #include "track.h" #include "utility.h" static struct { track_p Trk; coOrd orig; } Dpa; static DIST_T parSeparation = 1.0; static paramFloatRange_t r_0o1_100 = { 0.1, 100.0, 100 }; static paramData_t parSepPLs[] = { #define parSepPD (parSepPLs[0]) { PD_FLOAT, &parSeparation, "separation", PDO_DIM|PDO_NOPREF|PDO_NOPREF, &r_0o1_100, N_("Separation") } }; static paramGroup_t parSepPG = { "parallel", 0, parSepPLs, sizeof parSepPLs/sizeof parSepPLs[0] }; static STATUS_T CmdParallel( wAction_t action, coOrd pos ) { DIST_T d; track_p t=NULL; coOrd p; static coOrd p0, p1; ANGLE_T a; track_p t0, t1; EPINX_T ep0=-1, ep1=-1; wControl_p controls[2]; char * labels[1]; switch (action) { case C_START: if (parSepPD.control==NULL) { ParamCreateControls( &parSepPG, NULL ); } sprintf( message, "parallel-separation-%s", curScaleName ); parSeparation = ceil(13.0*12.0/curScaleRatio); wPrefGetFloat( "misc", message, &parSeparation, parSeparation ); ParamLoadControls( &parSepPG ); ParamGroupRecord( &parSepPG ); controls[0] = parSepPD.control; controls[1] = NULL; labels[0] = N_("Separation"); InfoSubstituteControls( controls, labels ); /*InfoMessage( "Select track" );*/ return C_CONTINUE; case C_DOWN: if ( parSeparation <= 0.0 ) { ErrorMessage( MSG_PARALLEL_SEP_GTR_0 ); return C_ERROR; } controls[0] = parSepPD.control; controls[1] = NULL; labels[0] = N_("Separation"); InfoSubstituteControls( controls, labels ); ParamLoadData( &parSepPG ); Dpa.orig = pos; Dpa.Trk = OnTrack( &Dpa.orig, TRUE, TRUE ); if (!Dpa.Trk) { return C_CONTINUE; } if ( !QueryTrack( Dpa.Trk, Q_CAN_PARALLEL ) ) { Dpa.Trk = NULL; InfoMessage(_(" Track doesn't support parallel")); return C_CONTINUE; } /* in case query has changed things (eg joint) */ /* * this seems to cause problems so I commented it out * until further investigation shows the necessity */ //Dpa.Trk = OnTrack( &Dpa.orig, TRUE, TRUE ); tempSegs_da.cnt = 0; case C_MOVE: if (Dpa.Trk == NULL) return C_CONTINUE; DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); if ( !MakeParallelTrack( Dpa.Trk, pos, parSeparation, NULL, &p0, &p1 ) ) { Dpa.Trk = NULL; return C_CONTINUE; } DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); return C_CONTINUE; case C_UP: if (Dpa.Trk == NULL) return C_CONTINUE; DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); p = p0; if ((t0=OnTrack( &p, FALSE, TRUE )) != NULL) { ep0 = PickEndPoint( p, t0 ); if ( GetTrkEndTrk(t0,ep0) != NULL ) { t0 = NULL; } else { p = GetTrkEndPos( t0, ep0 ); d = FindDistance( p, p0 ); if ( d > connectDistance ) t0 = NULL; } } p = p1; if ((t1=OnTrack( &p, FALSE, TRUE )) != NULL) { ep1 = PickEndPoint( p, t1 ); if ( GetTrkEndTrk(t1,ep1) != NULL ) { t1 = NULL; } else { p = GetTrkEndPos( t1, ep1 ); d = FindDistance( p, p1 ); if ( d > connectDistance ) t1 = NULL; } } UndoStart( _("Create Parallel Track"), "newParallel" ); if ( !MakeParallelTrack( Dpa.Trk, pos, parSeparation, &t, NULL, NULL ) ) { return C_TERMINATE; } CopyAttributes( Dpa.Trk, t ); if ( t0 ) { a = NormalizeAngle( GetTrkEndAngle( t0, ep0 ) - GetTrkEndAngle( t, 0 ) + (180.0+connectAngle/2.0) ); if (a < connectAngle) { DrawEndPt( &mainD, t0, ep0, wDrawColorWhite ); ConnectTracks( t0, ep0, t, 0 ); DrawEndPt( &mainD, t0, ep0, wDrawColorBlack ); } } if ( t1 ) { a = NormalizeAngle( GetTrkEndAngle( t1, ep1 ) - GetTrkEndAngle( t, 1 ) + (180.0+connectAngle/2.0) ); if (a < connectAngle) { DrawEndPt( &mainD, t1, ep1, wDrawColorWhite ); ConnectTracks( t1, ep1, t, 1 ); DrawEndPt( &mainD, t1, ep1, wDrawColorBlack ); } } DrawNewTrack( t ); UndoEnd(); InfoSubstituteControls( NULL, NULL ); sprintf( message, "parallel-separation-%s", curScaleName ); wPrefSetFloat( "misc", message, parSeparation ); return C_TERMINATE; case C_REDRAW: return C_CONTINUE; case C_CANCEL: InfoSubstituteControls( NULL, NULL ); return C_TERMINATE; } return C_CONTINUE; } #include "bitmaps/parallel.xpm" EXPORT void InitCmdParallel( wMenu_p menu ) { AddMenuButton( menu, CmdParallel, "cmdParallel", _("Parallel"), wIconCreatePixMap(parallel_xpm), LEVEL0_50, IC_STICKY|IC_POPUP, ACCL_PARALLEL, NULL ); ParamRegister( &parSepPG ); }