summaryrefslogtreecommitdiff
path: root/app/bin/cpull.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/cpull.c')
-rw-r--r--app/bin/cpull.c102
1 files changed, 89 insertions, 13 deletions
diff --git a/app/bin/cpull.c b/app/bin/cpull.c
index a10f426..d7f7c80 100644
--- a/app/bin/cpull.c
+++ b/app/bin/cpull.c
@@ -1,8 +1,5 @@
-/*
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/bin/cpull.c,v 1.4 2008-03-06 19:35:06 m_fischer Exp $
- *
+/** \file cpull.c
* Pull and Tighten commands
- *
*/
/* XTrkCad - Model Railroad CAD
@@ -24,14 +21,15 @@
*/
#include <math.h>
-#include "track.h"
+
#include "cselect.h"
#include "compound.h"
+#include "cundo.h"
+#include "fileio.h"
#include "i18n.h"
-
-/*
- * pull track endpoint together
- */
+#include "messages.h"
+#include "track.h"
+#include "utility.h"
int debugPull = 0;
@@ -454,12 +452,20 @@ static void PullTracks(
int cnt1, cnt2;
int rc;
+ if (QueryTrack(trk1,Q_CAN_ADD_ENDPOINTS) || QueryTrack(trk2,Q_CAN_ADD_ENDPOINTS)) {
+ ConnectTurntableTracks(trk1, ep1, trk2, ep2 );
+ return;
+ }
+
+ if (ep1<0 || ep1<0 ) return;
+
if (ConnectAbuttingTracks( trk1, ep1, trk2, ep2 ))
return;
if (ConnectAdjustableTracks( trk1, ep1, trk2, ep2 ))
return;
+
p1 = GetTrkEndPos( trk1, ep1 );
p2 = GetTrkEndPos( trk2, ep2 );
a1 = GetTrkEndAngle( trk1, ep1 );
@@ -593,12 +599,22 @@ static STATUS_T CmdPull(
static EPINX_T ep1;
track_p trk2;
EPINX_T ep2;
+ static BOOL_T turntable;
+
+ int countTracksR0 = 0, countTracksR1 = 0, possibleEndPoints = 0;
+ BOOL_T found = FALSE;
+ ANGLE_T a;
+ DIST_T d;
switch (action) {
case C_START:
- InfoMessage( _("Select first End-Point to connect") );
+ if (selectedTrackCount==0)
+ InfoMessage( _("Select first end-point to connect") );
+ else
+ InfoMessage( _("Select first end-point to connect, or Right-Click for connecting selected tracks") );
trk1 = NULL;
+ turntable = FALSE;
return C_CONTINUE;
case C_LCLICK:
@@ -606,10 +622,14 @@ static STATUS_T CmdPull(
if (trk1 == NULL) {
if ((trk1 = OnTrack( &pos, TRUE, FALSE )) != NULL) {
if ((ep1 = PickUnconnectedEndPoint( pos, trk1 )) < 0) {
- trk1 = NULL;
+ if (QueryTrack(trk1, Q_CAN_ADD_ENDPOINTS)) {
+ turntable = TRUE;
+ ep1 = -1;
+ } else trk1 = NULL;
} else {
- InfoMessage( _("Select second End-Point to connect") );
+ InfoMessage( _("Select second end-point to connect") );
}
+
}
} else {
if ((trk2 = OnTrack( &pos, TRUE, FALSE )) != NULL) {
@@ -619,6 +639,15 @@ static STATUS_T CmdPull(
inError = TRUE;
return C_TERMINATE;
}
+ if (!turntable && QueryTrack(trk2, Q_CAN_ADD_ENDPOINTS)) {
+ ep2 = -1;
+ turntable = TRUE;
+ PullTracks( trk2, ep2, trk1, ep1);
+ trk1 = NULL;
+ inError = TRUE;
+ turntable = FALSE;
+ return C_TERMINATE;
+ }
}
}
} else {
@@ -635,6 +664,53 @@ static STATUS_T CmdPull(
}
return C_CONTINUE;
+ case C_RCLICK:
+ if (selectedTrackCount==0) {
+ ErrorMessage(_("Connect Multiple Tracks - Select multiple tracks to join first"));
+ return C_CONTINUE;
+ }
+ if (NoticeMessage(_("Try to Connect all Selected Tracks?"), _("Yes"), _("No"))<=0) return C_CONTINUE;
+ trk1 = NULL;
+ trk2 = NULL;
+ UndoStart( _("ReConnect"),"Try to reconnect all selected tracks");
+ for (int i=0;i<2;i++) { // Try twice - in case later joins help earlier ones and to try close ones first
+ while ( TrackIterate( &trk1 ) ) {
+ found = FALSE;
+ if ( GetTrkSelected( trk1 ) ) {
+ for (ep1=0; ep1<GetTrkEndPtCnt(trk1); ep1++) {
+ if (!GetTrkEndTrk( trk1, ep1 )) {
+ trk2 = NULL;
+ while (!found && TrackIterate(&trk2) ) {
+ if (trk1 == trk2) continue;
+ for (ep2=0; ep2<GetTrkEndPtCnt(trk2); ep2++) {
+ if (GetTrkEndTrk( trk2, ep2 )) continue;
+ d = FindDistance(GetTrkEndPos(trk1,ep1),GetTrkEndPos(trk2,ep2));
+ a = NormalizeAngle( 180+GetTrkEndAngle( trk1, ep1 ) - GetTrkEndAngle( trk2, ep2 )+(connectAngle/2.0));
+ // Take two passes. In round one favor closer connections. In round two try anything.
+ if ( (i==0 && (d < connectDistance) && (a < connectAngle)) ||
+ (i>0 && (d<3.0 && a<7.5))) { // Match PullTracks criteria in round 2
+ PullTracks(trk1,ep1,trk2,ep2);
+ if (GetTrkEndTrk( trk2, ep2 )) {
+ found = TRUE;
+ if (i==0)
+ countTracksR0++;
+ else
+ countTracksR1++;
+ break; //Stop looking
+ } else if (i==1) possibleEndPoints++;
+ }
+ }
+ }
+ if (found) break; //Next EndPoint
+ }
+ }
+ }
+ }
+ }
+ UndoEnd();
+ NoticeMessage(_("Round 1 %d and Round 2 %d tracks connected, %d close pairs of end Points were not connected"), _("Ok"), NULL, countTracksR0, countTracksR1, possibleEndPoints);
+ return C_TERMINATE;
+
case C_REDRAW:
return C_CONTINUE;
@@ -658,5 +734,5 @@ static STATUS_T CmdPull(
void InitCmdPull( wMenu_p menu )
{
- AddMenuButton( menu, CmdPull, "cmdConnect", _("Connect Sectional Tracks"), wIconCreatePixMap(pull_xpm), LEVEL0_50, IC_STICKY|IC_LCLICK|IC_POPUP2, ACCL_CONNECT, NULL );
+ AddMenuButton( menu, CmdPull, "cmdConnect", _("Connect Two Tracks"), wIconCreatePixMap(pull_xpm), LEVEL0_50, IC_STICKY|IC_LCLICK|IC_POPUP2|IC_RCLICK, ACCL_CONNECT, NULL );
}