summaryrefslogtreecommitdiff
path: root/app/bin/cmodify.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/cmodify.c')
-rw-r--r--app/bin/cmodify.c490
1 files changed, 383 insertions, 107 deletions
diff --git a/app/bin/cmodify.c b/app/bin/cmodify.c
index 11f4c06..8f82012 100644
--- a/app/bin/cmodify.c
+++ b/app/bin/cmodify.c
@@ -34,6 +34,9 @@
#include "param.h"
#include "track.h"
#include "utility.h"
+#include "drawgeom.h"
+#include "common.h"
+#include "layout.h"
static struct {
track_p Trk;
@@ -47,10 +50,65 @@ static struct {
BOOL_T first;
} Dex;
+static wMenu_p modPopupM;
+
+extern wIndex_t selectCmdInx;
+extern wIndex_t joinCmdInx;
+extern wIndex_t describeCmdInx;
+
+static dynArr_t anchors_da;
+#define anchors(N) DYNARR_N(trkSeg_t,anchors_da,N)
static int log_modify;
static BOOL_T modifyBezierMode;
static BOOL_T modifyCornuMode;
+static BOOL_T modifyDrawMode;
+static BOOL_T modifyRulerMode;
+static BOOL_T modifyExtendMode;
+
+
+static void CreateEndAnchor(coOrd p, wBool_t lock) {
+ DIST_T d = tempD.scale*0.15;
+
+ DYNARR_APPEND(trkSeg_t,anchors_da,1);
+ int i = anchors_da.cnt-1;
+ anchors(i).type = lock?SEG_FILCRCL:SEG_CRVLIN;
+ anchors(i).color = wDrawColorBlue;
+ anchors(i).u.c.center = p;
+ anchors(i).u.c.radius = d/2;
+ anchors(i).u.c.a0 = 0.0;
+ anchors(i).u.c.a1 = 360.0;
+ anchors(i).width = 0;
+}
+
+static void CreateCornuAnchor(coOrd p, wBool_t lock) {
+ DIST_T d = tempD.scale*0.15;
+
+ DYNARR_APPEND(trkSeg_t,anchors_da,1);
+ int i = anchors_da.cnt-1;
+ anchors(i).type = lock?SEG_FILCRCL:SEG_CRVLIN;
+ anchors(i).color = wDrawColorBlue;
+ anchors(i).u.c.center = p;
+ anchors(i).u.c.radius = d/2;
+ anchors(i).u.c.a0 = 0.0;
+ anchors(i).u.c.a1 = 360.0;
+ anchors(i).width = 0;
+ DYNARR_APPEND(trkSeg_t,anchors_da,1);
+ i = anchors_da.cnt-1;
+ anchors(i).type = SEG_CRVLIN;
+ anchors(i).color = wDrawColorBlue;
+ anchors(i).u.c.center = p;
+ anchors(i).u.c.radius = d;
+ anchors(i).u.c.a0 = 0.0;
+ anchors(i).u.c.a1 = 360.0;
+ anchors(i).width = 0;
+}
+
+
+static void CreateRadiusAnchor(coOrd p, ANGLE_T a, BOOL_T bi) {
+ DYNARR_SET(trkSeg_t,anchors_da,anchors_da.cnt+5);
+ DrawArrowHeads(&DYNARR_N(trkSeg_t,anchors_da,anchors_da.cnt-5),p,a,bi,wDrawColorBlue);
+}
/*
* Call cbezier.c CmdBezModify to alter Bezier Track and Lines.
@@ -66,6 +124,7 @@ static STATUS_T ModifyBezier(wAction_t action, coOrd pos) {
case C_UP:
case C_OK:
case C_TEXT:
+ case wActionMove:
trackGauge = (IsTrack(Dex.Trk)?GetTrkGauge(Dex.Trk):0.0);
rc = CmdBezModify(Dex.Trk, action, pos, trackGauge);
break;
@@ -89,12 +148,14 @@ static STATUS_T ModifyCornu(wAction_t action, coOrd pos) {
STATUS_T rc = C_CONTINUE;
if (Dex.Trk == NULL) return C_ERROR; //No track picked yet!
switch (action&0xFF) {
+ case C_LCLICK:
case C_START:
case C_DOWN:
case C_MOVE:
case C_UP:
case C_OK:
case C_TEXT:
+ case wActionMove:
trackGauge = (IsTrack(Dex.Trk)?GetTrkGauge(Dex.Trk):0.0);
rc = CmdCornuModify(Dex.Trk, action, pos, trackGauge);
break;
@@ -110,7 +171,61 @@ static STATUS_T ModifyCornu(wAction_t action, coOrd pos) {
return rc;
}
-static STATUS_T CmdModify(
+/*
+ * Picking a DRAW will allow point modifications until terminated with "Enter"
+ */
+static STATUS_T ModifyDraw(wAction_t action, coOrd pos) {
+ STATUS_T rc = C_CONTINUE;
+ if (Dex.Trk == NULL) return C_ERROR; //No item picked yet!
+ switch (action&0xFF) {
+ case C_START:
+ case C_DOWN:
+ case C_MOVE:
+ case C_UP:
+ rc = ModifyTrack( Dex.Trk, action, pos );
+ break;
+ case wActionMove:
+ rc = ModifyTrack( Dex.Trk, action, pos );
+ break;
+ case C_TEXT:
+ //Delete or '0' - continues
+ if ((action>>8 !=32) && (action >>8 !=13))
+ return ModifyTrack( Dex.Trk, action, pos );
+ //Enter/Space does not
+ if ((action>>8 !=32) && (action>>8 != 13)) return C_CONTINUE;
+ /*no break*/
+ case C_OK:
+ UndoStart( _("Modify Track"), "Modify( T%d[%d] )", GetTrkIndex(Dex.Trk), Dex.params.ep );
+ UndoModify( Dex.Trk );
+ rc = ModifyTrack( Dex.Trk, C_TEXT | (13<<8), pos );
+ if (rc != C_CONTINUE) modifyDrawMode = FALSE;
+ UndoEnd();
+ break;
+ case C_CANCEL:
+ case C_FINISH:
+ case C_CONFIRM:
+ case C_TERMINATE:
+ rc = ModifyTrack( Dex.Trk, action, pos );
+ Dex.Trk = NULL;
+ modifyDrawMode = FALSE;
+ tempSegs_da.cnt = 0;
+ rc = C_CONTINUE;
+ break;
+ case C_REDRAW:
+ rc = ModifyTrack( Dex.Trk, action, pos );
+ break;
+ case C_CMDMENU:
+ menuPos = pos;
+ rc = ModifyTrack( Dex.Trk, action, pos );
+ break;
+ default:
+ break;
+ }
+ return rc;
+}
+
+
+STATUS_T CmdModify(
wAction_t action,
coOrd pos )
/*
@@ -128,7 +243,7 @@ static STATUS_T CmdModify(
EPINX_T inx;
curveType_e curveType;
static BOOL_T changeTrackMode;
- static BOOL_T modifyRulerMode;
+
STATUS_T rc;
static DIST_T trackGauge;
@@ -143,7 +258,8 @@ static STATUS_T CmdModify(
switch (action&0xFF) {
case C_START:
- InfoMessage( _("Select track to modify") );
+ DYNARR_RESET(trkSeg_t,anchors_da);
+ InfoMessage( _("Select a track to modify, Left-Click change length, Right-Click to add flextrack") );
Dex.Trk = NULL;
tempSegs_da.cnt = 0;
/*ChangeParameter( &easementPD );*/
@@ -151,21 +267,28 @@ static STATUS_T CmdModify(
changeTrackMode = modifyRulerMode = FALSE;
modifyBezierMode = FALSE;
modifyCornuMode = FALSE;
+ modifyDrawMode = FALSE;
+ modifyExtendMode = FALSE;
return C_CONTINUE;
case C_DOWN:
+ DYNARR_RESET(trkSeg_t,anchors_da);
if (modifyBezierMode)
return ModifyBezier(C_DOWN, pos);
if (modifyCornuMode)
return ModifyCornu(C_DOWN, pos);
+ if (modifyDrawMode)
+ return ModifyDraw(C_DOWN, pos);
+ /*no break*/
+ case C_LDOUBLE:
DYNARR_SET( trkSeg_t, tempSegs_da, 2 );
tempSegs(0).color = wDrawColorBlack;
tempSegs(0).width = 0;
tempSegs(1).color = wDrawColorBlack;
tempSegs(1).width = 0;
tempSegs_da.cnt = 0;
- SnapPos( &pos );
Dex.Trk = OnTrack( &pos, TRUE, FALSE );
+ //Dex.Trk = trk;
if (Dex.Trk == NULL) {
if ( ModifyRuler( C_DOWN, pos ) == C_CONTINUE )
modifyRulerMode = TRUE;
@@ -173,6 +296,7 @@ static STATUS_T CmdModify(
}
if (!CheckTrackLayer( Dex.Trk ) ) {
Dex.Trk = NULL;
+
return C_CONTINUE;
}
trackGauge = (IsTrack(Dex.Trk)?GetTrkGauge(Dex.Trk):0.0);
@@ -185,21 +309,38 @@ static STATUS_T CmdModify(
}
return C_CONTINUE; //That's it
}
- if (QueryTrack( Dex.Trk, Q_IS_CORNU )) { //Bezier
+ if (QueryTrack( Dex.Trk, Q_IS_CORNU )) { //Cornu
modifyCornuMode = TRUE;
if (ModifyCornu(C_START, pos) != C_CONTINUE) { //Call Start with track
- modifyCornuMode = FALSE; //Function rejected Bezier
+ modifyCornuMode = FALSE; //Function rejected Cornu
Dex.Trk =NULL;
tempSegs_da.cnt = 0;
+
}
return C_CONTINUE; //That's it
}
- if ( (MyGetKeyState()&WKEY_SHIFT) &&
+ if (QueryTrack( Dex.Trk, Q_IS_DRAW )) {
+ modifyDrawMode = TRUE;
+ if (ModifyDraw(C_START, pos) != C_CONTINUE) {
+ modifyDrawMode = FALSE;
+ Dex.Trk = NULL;
+ tempSegs_da.cnt = 0;
+ }
+ return C_CONTINUE;
+ }
+
+ if ((action&0xFF) == C_LDOUBLE) return C_ERROR;
+
+ if ((MyGetKeyState()&WKEY_CTRL)) goto extendTrack;
+
+
+
+ if ( (MyGetKeyState()&WKEY_SHIFT) && //Free to change radius
QueryTrack( Dex.Trk, Q_CAN_MODIFYRADIUS )&&
- (inx=PickUnconnectedEndPoint(pos,Dex.Trk)) >= 0 ) {
+ ((inx=PickUnconnectedEndPoint(pos,Dex.Trk)) >= 0 )) {
trk = Dex.Trk;
- while ( (trk1=GetTrkEndTrk(trk,1-inx)) &&
+ while ( (trk1=GetTrkEndTrk(trk,1-inx)) && //Means next track to mine even if can be end...
QueryTrack(trk1, Q_CANNOT_BE_ON_END) ) {
inx = GetEndPtConnectedToMe( trk1, trk );
trk = trk1;
@@ -208,7 +349,8 @@ static STATUS_T CmdModify(
UndoStart( _("Change Track"), "Change( T%d[%d] )", GetTrkIndex(Dex.Trk), Dex.params.ep );
inx = GetEndPtConnectedToMe( trk1, trk );
Dex.Trk = NULL;
- DeleteTrack(trk, TRUE);
+ UndrawNewTrack( trk );
+ DeleteTrack(trk, TRUE); //Get rid of original track
if ( !GetTrkEndTrk( trk1, inx ) ) {
Dex.Trk = trk1;
Dex.pos00 = GetTrkEndPos( Dex.Trk, inx );
@@ -218,16 +360,70 @@ static STATUS_T CmdModify(
}
ErrorMessage( MSG_CANNOT_CHANGE );
}
+ ModifyTrack(Dex.Trk, C_START, pos); //Basically trim via Modify...
rc = ModifyTrack( Dex.Trk, C_DOWN, pos );
if ( rc != C_CONTINUE ) {
Dex.Trk = NULL;
rc = C_CONTINUE;
}
- DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
- MainRedraw();
- MapRedraw();
return rc;
+ case wActionMove:
+ DYNARR_RESET(trkSeg_t,anchors_da);
+ if (modifyCornuMode) return ModifyCornu(wActionMove,pos);
+ if (modifyDrawMode) return ModifyDraw(wActionMove,pos);
+ if (modifyBezierMode) return ModifyBezier(wActionMove, pos);
+ track_p t;
+ if (((t=OnTrack(&pos,FALSE,TRUE))!= NULL) && CheckTrackLayerSilent( t )) {
+ EPINX_T ep = PickUnconnectedEndPointSilent(pos, t);
+ if (QueryTrack( t, Q_IS_CORNU )) {
+ CreateCornuAnchor(pos,FALSE);
+ } else if ( QueryTrack( t, Q_CAN_MODIFY_CONTROL_POINTS )) {
+ CreateRadiusAnchor(pos,NormalizeAngle(GetAngleAtPoint(t,pos,NULL,NULL)+90.0),TRUE);
+ CreateEndAnchor(pos,FALSE);
+ } else if (QueryTrack(t,Q_CAN_ADD_ENDPOINTS)){ //Turntable
+ trackParams_t tp;
+ if (!GetTrackParams(PARAMS_CORNU, t, pos, &tp)) return C_CONTINUE;
+ ANGLE_T a = tp.angle;
+ Translate(&pos,tp.ttcenter,a,tp.ttradius);
+ CreateRadiusAnchor(pos,a,FALSE);
+ } else if (QueryTrack(t,Q_CAN_EXTEND)) {
+ if (ep != -1) {
+ if (MyGetKeyState()&WKEY_CTRL) {
+ pos = GetTrkEndPos(t,ep);
+ CreateEndAnchor(pos,FALSE);
+ CreateRadiusAnchor(pos,GetTrkEndAngle(t,ep),FALSE);
+ CreateRadiusAnchor(pos,GetTrkEndAngle(t,ep)+90,TRUE);
+ } else {
+ CreateEndAnchor(pos,FALSE);
+ if ((MyGetKeyState()&WKEY_SHIFT) && //Shift Down
+ QueryTrack( t, Q_CAN_MODIFYRADIUS ) && // Straight or Curve
+ ((inx=PickUnconnectedEndPointSilent(pos,t)) >= 0 )) { //Which has an open end
+ if (GetTrkEndTrk(t,1-inx)) // Has to have a track on other end
+ CreateRadiusAnchor(pos,NormalizeAngle(GetAngleAtPoint(t,pos,NULL,NULL)+90.0),TRUE);
+ }
+ CreateRadiusAnchor(pos,GetAngleAtPoint(t,pos,NULL,NULL),TRUE);
+ }
+ }
+ } else if (ep>=0){ //Turnout
+ pos = GetTrkEndPos(t, ep);
+ CreateEndAnchor(pos,TRUE);
+ if ( (MyGetKeyState()&WKEY_CTRL)) {
+ CreateRadiusAnchor(pos,NormalizeAngle(GetTrkEndAngle(t,ep)),FALSE);
+ CreateRadiusAnchor(pos,GetTrkEndAngle(t,ep)+90,TRUE);
+ CreateEndAnchor(pos,TRUE);
+ } else {
+ CreateRadiusAnchor(pos,NormalizeAngle(GetTrkEndAngle(t,ep)),FALSE);
+ CreateEndAnchor(pos,TRUE);
+ }
+ }
+ } else if (((t=OnTrack(&pos,FALSE,FALSE))!= NULL)
+ && (!(GetLayerFrozen(GetTrkLayer(t)) && GetLayerModule(GetTrkLayer(t))))
+ && (QueryTrack(t, Q_IS_DRAW ) && !QueryTrack(t, Q_IS_TEXT)) ) {
+ CreateEndAnchor(pos,FALSE);
+ }
+ return C_CONTINUE;
+
case C_MOVE:
if ( modifyRulerMode )
return ModifyRuler( C_MOVE, pos );
@@ -237,21 +433,22 @@ static STATUS_T CmdModify(
return ModifyBezier(C_MOVE, pos);
if ( modifyCornuMode )
return ModifyCornu(C_MOVE, pos);
- DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
+ if ( modifyDrawMode)
+ return ModifyDraw(C_MOVE, pos);
+ if (modifyExtendMode && (MyGetKeyState()&WKEY_CTRL))
+ goto extendTrackMove;
tempSegs_da.cnt = 0;
+
SnapPos( &pos );
rc = ModifyTrack( Dex.Trk, C_MOVE, pos );
if ( rc != C_CONTINUE ) {
rc = C_CONTINUE;
Dex.Trk = NULL;
}
- DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
- MainRedraw();
- MapRedraw();
return rc;
-
case C_UP:
+ DYNARR_RESET(trkSeg_t,anchors_da);
if (Dex.Trk == NULL)
return C_CONTINUE;
if ( modifyRulerMode )
@@ -260,58 +457,71 @@ static STATUS_T CmdModify(
return ModifyBezier( C_UP, pos);
if (modifyCornuMode)
return ModifyCornu(C_UP, pos);
- DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
+ if (modifyDrawMode)
+ return ModifyDraw(C_UP, pos);
+ if ((MyGetKeyState()&WKEY_CTRL)) goto extendTrackUp;
+
tempSegs_da.cnt = 0;
+
SnapPos( &pos );
UndoStart( _("Modify Track"), "Modify( T%d[%d] )", GetTrkIndex(Dex.Trk), Dex.params.ep );
UndoModify( Dex.Trk );
rc = ModifyTrack( Dex.Trk, C_UP, pos );
UndoEnd();
- //changeTrackMode = FALSE;
Dex.Trk = NULL;
- MainRedraw();
- MapRedraw();
return rc;
- case C_RDOWN:
+ case C_RDOWN: //This is same as context menu....
+extendTrack:
+ DYNARR_RESET(trkSeg_t,anchors_da);
changeTrackMode = TRUE;
+ modifyExtendMode = TRUE;
modifyRulerMode = FALSE;
modifyBezierMode = FALSE;
modifyCornuMode = FALSE;
- Dex.Trk = OnTrack( &pos, TRUE, TRUE );
- if (Dex.Trk) {
- if (!CheckTrackLayer( Dex.Trk ) ) {
- Dex.Trk = NULL;
- return C_CONTINUE;
- }
- trackGauge = GetTrkGauge( Dex.Trk );
- Dex.pos00 = pos;
-CHANGE_TRACK:
- if (GetTrackParams( PARAMS_EXTEND, Dex.Trk, Dex.pos00, &Dex.params)) {
- if (Dex.params.ep == -1) {
+ modifyDrawMode = FALSE;
+ Dex.first = FALSE;
+ if (((action&0xFF) == C_RDOWN) || ((action&0xFF)== C_DOWN)) {
+ Dex.Trk = OnTrack( &pos, TRUE, TRUE );
+ if (Dex.Trk) {
+ if (!CheckTrackLayer( Dex.Trk ) ) {
Dex.Trk = NULL;
return C_CONTINUE;
- break;
}
- if (Dex.params.ep == 0) {
- Dex.params.arcR = -Dex.params.arcR;
+ trackGauge = GetTrkGauge( Dex.Trk );
+ Dex.pos00 = pos;
+ CHANGE_TRACK:
+ if (GetTrackParams( PARAMS_EXTEND, Dex.Trk, Dex.pos00, &Dex.params)) {
+ if (Dex.params.ep == -1) {
+ Dex.Trk = NULL;
+ return C_CONTINUE;
+ break;
+ }
+ if (Dex.params.ep == 0) {
+ Dex.params.arcR = -Dex.params.arcR;
+ }
+ Dex.pos00 = GetTrkEndPos(Dex.Trk,Dex.params.ep);
+ Dex.angle = GetTrkEndAngle( Dex.Trk,Dex.params.ep);
+ Translate( &Dex.pos00x, Dex.pos00, Dex.angle, 10.0 );
+ LOG( log_modify, 1, ("extend endPt[%d] = [%0.3f %0.3f] A%0.3f\n",
+ Dex.params.ep, Dex.pos00.x, Dex.pos00.y, Dex.angle ) )
+ InfoMessage( _("Drag to add flex track") );
+ } else {
+ return C_ERROR;
}
- Dex.pos00 = GetTrkEndPos(Dex.Trk,Dex.params.ep);
- Dex.angle = GetTrkEndAngle( Dex.Trk,Dex.params.ep);
- Translate( &Dex.pos00x, Dex.pos00, Dex.angle, 10.0 );
-LOG( log_modify, 1, ("extend endPt[%d] = [%0.3f %0.3f] A%0.3f\n",
- Dex.params.ep, Dex.pos00.x, Dex.pos00.y, Dex.angle ) )
- InfoMessage( _("Drag to create new track segment") );
} else {
+ InfoMessage ( _("No track to extend"));
return C_ERROR;
}
+ Dex.first = TRUE;
+ } else if (!Dex.Trk) {
+ InfoMessage ( _("No track selected"));
+ return C_ERROR;
}
- Dex.first = TRUE;
- MainRedraw();
- MapRedraw();
/* no break */
case C_RMOVE:
- DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
+extendTrackMove:
+ DYNARR_RESET(trkSeg_t,anchors_da);
tempSegs_da.cnt = 0;
Dex.valid = FALSE;
if (Dex.Trk == NULL) return C_CONTINUE;
@@ -320,7 +530,8 @@ LOG( log_modify, 1, ("extend endPt[%d] = [%0.3f %0.3f] A%0.3f\n",
return C_CONTINUE;
Dex.first = FALSE;
Dex.pos01 = Dex.pos00;
- if (Dex.params.type == curveTypeCornu) { //Restrict Cornu drag out to match end
+
+ if (Dex.params.type == curveTypeCornu) { //Always Restrict Cornu drag out to match end
ANGLE_T angle2 = NormalizeAngle(FindAngle(pos, Dex.pos00)-Dex.angle);
if (angle2 > 90.0 && angle2 < 270.0) {
if (Dex.params.cornuRadius[Dex.params.ep] == 0) {
@@ -346,11 +557,6 @@ LOG( log_modify, 1, ("extend endPt[%d] = [%0.3f %0.3f] A%0.3f\n",
ErrorMessage( MSG_TRK_TOO_SHORT, "First ", PutDim(fabs(minLength-d)) );
return C_CONTINUE;
}
- a0 = Dex.angle + (Dex.jointD.negate?-90.0:+90.0);
- Translate( &Dex.pos01, Dex.pos00, a0, Dex.jointD.x );
- Translate( &Dex.curveData.pos1, Dex.curveData.pos1,
- a0, Dex.jointD.x );
-LOG( log_modify, 2, ("A=%0.3f X=%0.3f\n", a0, Dex.jointD.x ) )
} else {
Dex.jointD.d1 = 0.0;
}
@@ -376,44 +582,55 @@ LOG( log_modify, 2, ("A=%0.3f X=%0.3f\n", a0, Dex.jointD.x ) )
return C_CONTINUE;
} else if ( curveType == curveTypeCurve ) {
Dex.r1 = Dex.curveData.curveRadius;
- if ( easeR > 0.0 && Dex.r1 < easeR ) {
- ErrorMessage( MSG_RADIUS_LSS_EASE_MIN,
- FormatDistance( Dex.r1 ), FormatDistance( easeR ) );
- return C_CONTINUE;
- }
- if ( Dex.r1*2.0*M_PI*Dex.curveData.a1/360.0 > mapD.size.x+mapD.size.y ) {
- ErrorMessage( MSG_CURVE_TOO_LARGE );
- return C_CONTINUE;
- }
- if ( NormalizeAngle( FindAngle( Dex.pos00, pos ) - Dex.angle ) > 180.0 )
- Dex.r1 = -Dex.r1;
if ( QueryTrack( Dex.Trk, Q_IGNORE_EASEMENT_ON_EXTEND ) ) {
- /* Ignore easements when extending turnouts */
+ /* Ignore easements when extending turnouts or turntables */
Dex.jointD.x =
Dex.jointD.r0 = Dex.jointD.r1 =
Dex.jointD.l0 = Dex.jointD.l1 =
Dex.jointD.d0 = Dex.jointD.d1 = 0.0;
Dex.jointD.flip = Dex.jointD.negate = Dex.jointD.Scurve = FALSE;
- } else {
- if (ComputeJoint( Dex.params.arcR, Dex.r1, &Dex.jointD ) == E_ERROR)
- return C_CONTINUE;
- d = Dex.params.len - Dex.jointD.d0;
- if (d <= minLength) {
- ErrorMessage( MSG_TRK_TOO_SHORT, "First ", PutDim(fabs(minLength-d)) );
- return C_CONTINUE;
+ d = Dex.curveData.curveRadius * Dex.curveData.a1 * 2.0*M_PI/360.0;
+ } else { /* Easement code */
+ if (easementVal<0.0) { //Cornu Join - need to estimate a "good" easement length
+ d = Dex.curveData.curveRadius * Dex.curveData.a1 * 2.0*M_PI/360.0;
+ Dex.jointD.d0 = Dex.jointD.d1 =0.75*72*12/GetTrkScale(Dex.Trk); //Easement 1.5 cars long to start
+ if (Dex.jointD.d0>(GetTrkLength(Dex.Trk,0,1)/2))
+ Dex.jointD.d0 = GetTrkLength(Dex.Trk,0,1)/2;
+ if (Dex.jointD.d1>d/2)
+ Dex.jointD.d1 = d/2;
+ Dex.jointD.negate = DifferenceBetweenAngles(Dex.angle,FindAngle(Dex.pos00,pos))<0.0;
+ Dex.jointD.x = 2*trackGauge; //Signal an easement present to JoinTracks
+ } else {
+ if ( easeR > 0.0 && Dex.r1 < easeR ) {
+ ErrorMessage( MSG_RADIUS_LSS_EASE_MIN,
+ FormatDistance( Dex.r1 ), FormatDistance( easeR ) );
+ return C_CONTINUE;
+ }
+ if ( Dex.r1*2.0*M_PI*Dex.curveData.a1/360.0 > mapD.size.x+mapD.size.y ) {
+ ErrorMessage( MSG_CURVE_TOO_LARGE );
+ return C_CONTINUE;
+ }
+ if ( NormalizeAngle( FindAngle( Dex.pos00, pos ) - Dex.angle ) > 180.0 )
+ Dex.r1 = - Dex.r1;
+ if (ComputeJoint( Dex.params.arcR, Dex.r1, &Dex.jointD ) == E_ERROR)
+ return C_CONTINUE;
+ d = Dex.params.len - Dex.jointD.d0;
+ if (d <= minLength) {
+ ErrorMessage( MSG_TRK_TOO_SHORT, "First ", PutDim(fabs(minLength-d)) );
+ return C_CONTINUE;
+ }
}
+ d -= Dex.jointD.d1;
+ a0 = Dex.angle + (Dex.jointD.negate?-90.0:+90.0);
+ Translate( &Dex.pos01, Dex.pos00, a0, Dex.jointD.x );
+ Translate( &Dex.curveData.curvePos, Dex.curveData.curvePos,
+ a0, Dex.jointD.x );
+LOG( log_modify, 2, ("A=%0.3f X=%0.3f\n", a0, Dex.jointD.x ) )
}
- d = Dex.curveData.curveRadius * Dex.curveData.a1 * 2.0*M_PI/360.0;
- d -= Dex.jointD.d1;
if (d <= minLength) {
ErrorMessage( MSG_TRK_TOO_SHORT, "Extending ", PutDim(fabs(minLength-d)) );
return C_CONTINUE;
}
- a0 = Dex.angle + (Dex.jointD.negate?-90.0:+90.0);
- Translate( &Dex.pos01, Dex.pos00, a0, Dex.jointD.x );
- Translate( &Dex.curveData.curvePos, Dex.curveData.curvePos,
- a0, Dex.jointD.x );
-LOG( log_modify, 2, ("A=%0.3f X=%0.3f\n", a0, Dex.jointD.x ) )
tempSegs(0).type = SEG_CRVTRK;
tempSegs(0).width = 0;
tempSegs(0).u.c.center = Dex.curveData.curvePos;
@@ -421,9 +638,9 @@ LOG( log_modify, 2, ("A=%0.3f X=%0.3f\n", a0, Dex.jointD.x ) )
tempSegs(0).u.c.a0 = Dex.curveData.a0;
tempSegs(0).u.c.a1 = Dex.curveData.a1;
tempSegs_da.cnt = 1;
- d = D2R(Dex.curveData.a1);
- if (d < 0.0)
- d = 2*M_PI + d;
+ double da = D2R(Dex.curveData.a1);
+ if (da < 0.0)
+ da = 2*M_PI + da;
a = NormalizeAngle( Dex.angle - FindAngle( Dex.pos00, Dex.curveData.curvePos ) );
if ( a < 180.0 )
a = NormalizeAngle( Dex.curveData.a0-90 );
@@ -433,17 +650,15 @@ LOG( log_modify, 2, ("A=%0.3f X=%0.3f\n", a0, Dex.jointD.x ) )
if (action != C_RDOWN)
InfoMessage( _("Curve Track: Radius=%s Length=%s Angle=%0.3f"),
FormatDistance( Dex.curveData.curveRadius ),
- FormatDistance( Dex.curveData.curveRadius * d),
+ FormatDistance( Dex.curveData.curveRadius * da),
Dex.curveData.a1 );
}
- DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
- MainRedraw();
- MapRedraw();
return C_CONTINUE;
case C_RUP:
+extendTrackUp:
changeTrackMode = FALSE;
- DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
+ modifyExtendMode = FALSE;
tempSegs_da.cnt = 0;
if (Dex.Trk == NULL) return C_CONTINUE;
if (!Dex.valid)
@@ -453,22 +668,24 @@ LOG( log_modify, 2, ("A=%0.3f X=%0.3f\n", a0, Dex.jointD.x ) )
curveType = Dex.curveData.type;
if ( curveType == curveTypeStraight ) {
- if ( Dex.params.type == curveTypeStraight && Dex.params.len > 0 ) {
- //UndrawNewTrack( Dex.Trk );
- UndoModify( Dex.Trk );
- AdjustStraightEndPt( Dex.Trk, Dex.params.ep, Dex.curveData.pos1 );
- UndoEnd();
- DrawNewTrack(Dex.Trk );
- MainRedraw();
- MapRedraw();
- return C_TERMINATE;
+ if (QueryTrack(Dex.Trk,Q_CAN_EXTEND)) //Check it isn't a turnout end....
+ if ( Dex.params.type == curveTypeStraight &&
+ FindDistance(Dex.pos01, Dex.curveData.pos1) > 0 ) {
+ UndoModify( Dex.Trk );
+ AdjustStraightEndPt( Dex.Trk, Dex.params.ep, Dex.curveData.pos1 );
+ UndoEnd();
+ DrawNewTrack(Dex.Trk );
+ return C_TERMINATE;
}
+ if (FindDistance(Dex.pos01, Dex.curveData.pos1) == 0) return C_ERROR;
+LOG( log_modify, 1, ("L = %0.3f, P0 = %0.3f, P1 = %0.3f\n",
+ Dex.params.len, Dex.pos01, Dex.curveData.pos1 ) )
trk = NewStraightTrack( Dex.pos01, Dex.curveData.pos1 );
inx = 0;
} else if ( curveType == curveTypeCurve ) {
-LOG( log_modify, 1, ("A0 = %0.3f, A1 = %0.3f\n",
- Dex.curveData.a0, Dex.curveData.a1 ) )
+LOG( log_modify, 1, ("R = %0.3f, A0 = %0.3f, A1 = %0.3f\n",
+ Dex.curveData.curveRadius, Dex.curveData.a0, Dex.curveData.a1 ) )
trk = NewCurvedTrack( Dex.curveData.curvePos, Dex.curveData.curveRadius,
Dex.curveData.a0, Dex.curveData.a1, 0 );
inx = PickUnconnectedEndPoint( Dex.pos01, trk );
@@ -478,39 +695,86 @@ LOG( log_modify, 1, ("A0 = %0.3f, A1 = %0.3f\n",
} else {
return C_ERROR;
}
- //UndrawNewTrack( Dex.Trk );
CopyAttributes( Dex.Trk, trk );
- JoinTracks( Dex.Trk, Dex.params.ep, Dex.pos00, trk, inx, Dex.pos01, &Dex.jointD );
+ if (Dex.jointD.d1 == 0) {
+ DrawEndPt( &mainD, Dex.Trk, Dex.params.ep, wDrawColorWhite );
+ ConnectTracks(Dex.Trk, Dex.params.ep, trk, inx);
+ DrawEndPt( &mainD, Dex.Trk, Dex.params.ep, wDrawColorBlack );
+ } else {
+ UndrawNewTrack( Dex.Trk );
+ JoinTracks( Dex.Trk, Dex.params.ep, Dex.pos00, trk, inx, Dex.pos01, &Dex.jointD );
+ DrawNewTrack( Dex.Trk );
+ }
UndoEnd();
+ tempSegs_da.cnt = 0;
DrawNewTrack( trk );
- DrawNewTrack( Dex.Trk );
- Dex.Trk = NULL;
- MainRedraw();
- MapRedraw();
return C_TERMINATE;
case C_REDRAW:
if (modifyBezierMode) return ModifyBezier(C_REDRAW, pos);
if (modifyCornuMode) return ModifyCornu(C_REDRAW, pos);
- if ( (!changeTrackMode) && Dex.Trk && !QueryTrack( Dex.Trk, Q_MODIFY_REDRAW_DONT_UNDRAW_TRACK ) )
- UndrawNewTrack( Dex.Trk );
+ if (modifyDrawMode) return ModifyDraw(C_REDRAW, pos);
DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
+ if (anchors_da.cnt)
+ DrawSegs( &tempD, zero, 0.0, &anchors(0), anchors_da.cnt, trackGauge, wDrawColorBlack );
+
return C_CONTINUE;
case C_TEXT:
+ if ((action>>8) == 'c') {
+ panCenter = pos;
+ LOG( log_pan, 2, ( "PanCenter:Mod-%d %0.3f %0.3f\n", __LINE__, panCenter.x, panCenter.y ) );
+ PanHere((void*)0);
+ return C_CONTINUE;
+ }
+ if ((action>>8) == 'e') {
+ DoZoomExtents(0);
+ }
+ if ((action>>8) == '0' || (action>>8 == 'o')) {
+ PanMenuEnter('o');
+ }
if ( !Dex.Trk )
return C_CONTINUE;
if (modifyBezierMode)
return ModifyBezier(action, pos);
if (modifyCornuMode)
return ModifyCornu(action, pos);
+ if (modifyDrawMode)
+ return ModifyDraw(action, pos);
+ return ModifyTrack( Dex.Trk, action, pos );
+
+ case C_CMDMENU:
+ if ( !Dex.Trk ) {
+ menuPos = pos;
+ wMenuPopupShow(modPopupM);
+ return C_CONTINUE;
+ }
+ if (modifyBezierMode)
+ return ModifyBezier(action, pos);
+ if (modifyCornuMode)
+ return ModifyCornu(action, pos);
+ if (modifyDrawMode)
+ return ModifyDraw(action, pos);
return ModifyTrack( Dex.Trk, action, pos );
+ case C_LCLICK:
+ if ( modifyDrawMode) {
+ rc = ModifyDraw(C_DOWN, pos);
+ if (rc == C_CONTINUE)
+ return ModifyDraw(C_UP, pos);
+ }
+ if (modifyCornuMode)
+ return ModifyCornu(action, pos);
+ /*no break*/
default:
if (modifyBezierMode) return ModifyBezier(action, pos);
if (modifyCornuMode) return ModifyCornu(action, pos);
+ if (modifyDrawMode) return ModifyDraw(action, pos);
+ if (Dex.Trk)
+ return ModifyTrack( Dex.Trk, action, pos );
return C_CONTINUE;
}
+ return C_CONTINUE;
}
@@ -521,9 +785,21 @@ LOG( log_modify, 1, ("A0 = %0.3f, A1 = %0.3f\n",
*/
#include "bitmaps/extend.xpm"
+extern wIndex_t panCmdInx;
+extern wIndex_t selectCmdInx;
+extern wIndex_t describeCmdInx;
+
void InitCmdModify( wMenu_p menu )
{
- modifyCmdInx = AddMenuButton( menu, CmdModify, "cmdModify", _("Modify"), wIconCreatePixMap(extend_xpm), LEVEL0_50, IC_STICKY|IC_POPUP, ACCL_MODIFY, NULL );
+ modifyCmdInx = AddMenuButton( menu, CmdModify, "cmdModify", _("Modify"), wIconCreatePixMap(extend_xpm), LEVEL0_50, IC_STICKY|IC_POPUP|IC_WANT_MOVE|IC_CMDMENU, ACCL_MODIFY, NULL );
log_modify = LogFindIndex( "modify" );
+ modPopupM = MenuRegister( "Modify Context Menu" );
+ wMenuPushCreate(modPopupM, "cmdSelectMode", GetBalloonHelpStr("cmdSelectMode"), 0, DoCommandB, (void*) (intptr_t) selectCmdInx);
+ wMenuPushCreate(modPopupM, "cmdDescribeMode", GetBalloonHelpStr("cmdDescribeMode"), 0, DoCommandB, (void*) (intptr_t) describeCmdInx);
+ wMenuPushCreate(modPopupM, "cmdPanMode", GetBalloonHelpStr("cmdPanMode"), 0, DoCommandB, (void*) (intptr_t) panCmdInx);
+ wMenuSeparatorCreate(modPopupM);
+ wMenuPushCreate(modPopupM, "", _("Zoom In"), 0,(wMenuCallBack_p) DoZoomUp, (void*) 1);
+ wMenuPushCreate(modPopupM, "", _("Zoom Out"), 0, (wMenuCallBack_p) DoZoomDown, (void*) 1);
+ wMenuPushCreate(modPopupM, "", _("Pan center - 'c'"), 0, (wMenuCallBack_p) PanHere, (void*) 3);
}