diff options
Diffstat (limited to 'app/bin/ccurve.c')
-rw-r--r-- | app/bin/ccurve.c | 167 |
1 files changed, 97 insertions, 70 deletions
diff --git a/app/bin/ccurve.c b/app/bin/ccurve.c index e119610..2308bd1 100644 --- a/app/bin/ccurve.c +++ b/app/bin/ccurve.c @@ -20,9 +20,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <math.h> -#include <string.h> - #include "ccurve.h" #include "cjoin.h" @@ -30,17 +27,14 @@ #include "cundo.h" #include "custom.h" #include "fileio.h" -#include "i18n.h" +#include "cselect.h" -#include "messages.h" -#include "param.h" #include "param.h" #include "track.h" -#include "utility.h" -#include "wlib.h" #include "cbezier.h" #include "ccornu.h" #include "layout.h" +#include "common-ui.h" /* * STATE INFO @@ -213,7 +207,7 @@ EXPORT STATUS_T CreateCurve( } } } else { - if ((t = OnTrack(&p, FALSE, FALSE)) != NULL) { + if (((t = OnTrack(&p, FALSE, FALSE)) != NULL) && IsClose(FindDistance(p,pos))) { if (!IsTrack(t)) { pos = p; found = TRUE; @@ -221,7 +215,8 @@ EXPORT STATUS_T CreateCurve( } } Da.down = TRUE; - if (!found) SnapPos( &pos ); + if (!found && !track) SnapPos( &pos ); + if (mode == crvCmdFromCenter) SnapPos( &pos ); Da.lock0 = found; if (Da.create_state == NOCURVE) @@ -279,7 +274,7 @@ EXPORT STATUS_T CreateCurve( DYNARR_RESET(trkSeg_t,*anchor_array); DYNARR_APPEND(trkSeg_t,*anchor_array,1); if (!Da.down) return C_CONTINUE; - if (Da.trk && !(MyGetKeyState() & WKEY_SHIFT)) { //Shift inhibits direction lock + if (Da.trk && track && !(MyGetKeyState() & WKEY_SHIFT)) { //Shift inhibits direction lock angle1 = NormalizeAngle(GetTrkEndAngle(Da.trk, Da.ep)); angle2 = NormalizeAngle(FindAngle(pos, Da.pos0)-angle1); if (mode ==crvCmdFromEP1 ) { @@ -302,7 +297,7 @@ EXPORT STATUS_T CreateCurve( DIST_T dp = FindDistance(Da.pos0, pos)*sin(D2R(angle2)); Translate( &pos, Da.pos0, angle1-90.0, dp ); } - } else SnapPos(&pos); + } else if (track) SnapPos(&pos); tempSegs_da.cnt =1; if (Da.trk && mode == crvCmdFromChord) { tempSegs(0).type = SEG_CRVTRK; @@ -400,7 +395,7 @@ EXPORT STATUS_T CreateCurve( } break; } - message( _("Drag on Red arrows to adjust curve") ); + //message( _("Drag on Red arrows to adjust curve") ); return C_CONTINUE; default: @@ -409,7 +404,16 @@ EXPORT STATUS_T CreateCurve( } } +static DIST_T desired_radius = 0.0; +static BOOL_T infoSubst = FALSE; +static paramFloatRange_t r_0_10000 = { 0.0, 100000.0 }; +static paramData_t curvePLs[] = { +#define curveRadPD (curvePLs[0]) +#define curveRadI 0 + { PD_FLOAT, &desired_radius, "radius", PDO_DIM, &r_0_10000, N_("Desired Radius") } +}; +static paramGroup_t curvePG = { "curvefixed", 0, curvePLs, COUNT( curvePLs ) }; static STATUS_T CmdCurve( wAction_t action, coOrd pos ) { @@ -417,39 +421,32 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos ) DIST_T d; static int segCnt; STATUS_T rc = C_CONTINUE; + wControl_p controls[2]; + char * labels[1]; + static BOOL_T lock; + static coOrd movePos; + switch (action) { case C_START: - curveMode = (long)commandContext; + lock = FALSE; + curveMode = VP2L(commandContext); Da.state = -1; Da.pos0 = pos; tempSegs_da.cnt = 0; segCnt = 0; STATUS_T rcode; DYNARR_RESET(trkSeg_t,anchors_da); + if (curvePLs[0].control==NULL) { + ParamCreateControls(&curvePG, NULL); + } + SetAllTrackSelect(FALSE); return CreateCurve( action, pos, TRUE, wDrawColorBlack, 0, curveMode, &anchors_da, InfoMessage ); case C_DOWN: if (Da.state == -1) { - BOOL_T found = FALSE; - if (curveMode != crvCmdFromCenter ) { - if (((MyGetKeyState() & WKEY_ALT)==0) == magneticSnap) { - if ((t = OnTrack(&pos,FALSE,TRUE))!=NULL) { - EPINX_T ep = PickUnconnectedEndPointSilent(pos, t); - if (ep != -1) { - if (GetTrkGauge(t) != GetScaleTrackGauge(GetLayoutCurScale())) { - wBeep(); - InfoMessage(_("Track is different gauge")); - return C_CONTINUE; - } - pos = GetTrkEndPos(t, ep); - found = TRUE; - } - } - } - } - if (!found) SnapPos( &pos ); + if (lock) pos = movePos; Da.pos0 = Da.pos1 = pos; Da.state = 0; rcode = CreateCurve( action, pos, TRUE, wDrawColorBlack, 0, curveMode, &anchors_da, InfoMessage ); @@ -458,12 +455,19 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos ) return rcode; //Da.pos0 = pos; } + if (infoSubst) { + sprintf(message, "desired_radius-%s", curScaleName); + wPrefSetFloat("misc", message, desired_radius); + InfoSubstituteControls(NULL, NULL); + } + infoSubst = FALSE; //This is where the user could adjust - if we allow that? tempSegs_da.cnt = segCnt; return C_CONTINUE; case wActionMove: + lock = FALSE; if ((Da.state<0) && (curveMode != crvCmdFromCenter)) { DYNARR_RESET(trkSeg_t,anchors_da); if (((MyGetKeyState() & WKEY_ALT)==0) == magneticSnap) { @@ -473,10 +477,17 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos ) if (ep != -1) { pos = GetTrkEndPos(t, ep); CreateEndAnchor(pos,&anchors_da,FALSE); + lock = TRUE; + movePos = pos; } } } } + if (!lock && SnapPos(&pos)) { + CreateEndAnchor(pos,&anchors_da,FALSE); + lock = TRUE; + movePos = pos; + } } return C_CONTINUE; @@ -490,8 +501,8 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos ) DYNARR_RESET(trkSeg_t,anchors_da); // SnapPos( &pos ); tempSegs_da.cnt = segCnt; - if (Da.trk) PlotCurve( curveMode, Da.pos0, Da.pos1, pos, &Da.curveData, FALSE ); - else PlotCurve( curveMode, Da.pos0, Da.pos1, pos, &Da.curveData, TRUE ); + if (Da.trk) PlotCurve( curveMode, Da.pos0, Da.pos1, pos, &Da.curveData, FALSE, desired_radius ); + else PlotCurve( curveMode, Da.pos0, Da.pos1, pos, &Da.curveData, TRUE, desired_radius ); if (Da.curveData.type == curveTypeStraight) { tempSegs(0).type = SEG_STRTRK; tempSegs(0).u.l.pos[0] = Da.pos0; @@ -514,14 +525,15 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos ) tempSegs(0).u.c.a1 = Da.curveData.a1; tempSegs_da.cnt = 1; segCnt = 1; + d = D2R(Da.curveData.a1); + if (d < 0.0) d = 2*M_PI+d; if ( d*Da.curveData.curveRadius > mapD.size.x+mapD.size.y ) { ErrorMessage( MSG_CURVE_TOO_LARGE ); tempSegs_da.cnt = 0; Da.curveData.type = curveTypeNone; - mainD.funcs->options = 0; return C_CONTINUE; } InfoMessage( _("Curved Track: Radius=%s Angle=%0.3f Length=%s"), @@ -532,13 +544,18 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos ) if (curveMode == crvCmdFromEP1 || curveMode == crvCmdFromChord) DrawArrowHeadsArray(&anchors_da,pos,FindAngle(Da.curveData.curvePos,pos),TRUE,wDrawColorRed); else if (curveMode == crvCmdFromTangent || curveMode == crvCmdFromCenter) { - CreateEndAnchor(Da.curveData.pos2,&anchors_da,FALSE); + if (Da.curveData.curveRadius == desired_radius) + CreateEndAnchor(Da.curveData.pos2,&anchors_da,TRUE); + else + CreateEndAnchor(Da.curveData.pos2,&anchors_da,FALSE); DrawArrowHeadsArray(&anchors_da,Da.curveData.pos2,FindAngle(Da.curveData.curvePos,Da.curveData.pos2)+90,TRUE,wDrawColorRed); } - CreateEndAnchor(Da.curveData.curvePos,&anchors_da,TRUE); + if (Da.curveData.curveRadius == desired_radius) + CreateEndAnchor(Da.curveData.curvePos,&anchors_da,TRUE); + else + CreateEndAnchor(Da.curveData.curvePos,&anchors_da,FALSE); } } - mainD.funcs->options = 0; return rc; case C_TEXT: if ( Da.state == 0 ) @@ -547,8 +564,8 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos ) case C_UP: if (Da.state<0) return C_CONTINUE; if (Da.state == 0 && ((curveMode != crvCmdFromChord) || (curveMode == crvCmdFromChord && !Da.trk))) { - SnapPos( &pos ); - Da.pos1 = pos; + //SnapPos( &pos ); + //Da.pos1 = pos; if ((d = FindDistance(Da.pos0,Da.pos1))<minLength) { ErrorMessage( MSG_TRK_TOO_SHORT, "Curved ", PutDim(fabs(minLength-d)) ); return C_TERMINATE; @@ -556,9 +573,20 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos ) Da.state = 1; CreateCurve( action, pos, TRUE, wDrawColorBlack, 0, curveMode, &anchors_da, InfoMessage ); tempSegs_da.cnt = 1; - mainD.funcs->options = 0; segCnt = tempSegs_da.cnt; - InfoMessage( _("Drag on Red arrows to adjust curve") ); + + sprintf(message, "desired_radius-%s", curScaleName); + wPrefGetFloat("misc", message, &desired_radius, desired_radius); + controls[0] = curveRadPD.control; + controls[1] = NULL; + labels[0] = N_("Desired Radius"); + InfoSubstituteControls(controls, labels); + infoSubst = TRUE; + curveRadPD.option |= PDO_NORECORD; + ParamLoadControls(&curvePG); + ParamGroupRecord(&curvePG); + //InfoMessage( _("Drag on Red arrows to adjust curve") ); + return C_CONTINUE; } else if ((curveMode == crvCmdFromChord && Da.state == 0 && Da.trk)) { pos = Da.middle; @@ -566,9 +594,8 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos ) ErrorMessage( MSG_TRK_TOO_SHORT, "Curved ", PutDim(fabs(minLength-d)) ); return C_TERMINATE; } - PlotCurve( curveMode, Da.pos0, Da.pos1, Da.middle, &Da.curveData, TRUE ); + PlotCurve( curveMode, Da.pos0, Da.pos1, Da.middle, &Da.curveData, TRUE, desired_radius ); } - mainD.funcs->options = 0; tempSegs_da.cnt = 0; segCnt = 0; Da.state = -1; @@ -590,6 +617,7 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos ) ErrorMessage( MSG_TRK_TOO_SHORT, "Curved ", PutDim(fabs(minLength-d)) ); return C_TERMINATE; } + UndoStart( _("Create Curved Track"), "newCurve - curve" ); t = NewCurvedTrack( Da.curveData.curvePos, Da.curveData.curveRadius, Da.curveData.a0, Da.curveData.a1, 0 ); @@ -607,7 +635,6 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos ) case C_REDRAW: if ( Da.state >= 0 ) { DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); - mainD.funcs->options = 0; } if (anchors_da.cnt) DrawSegs( &tempD, zero, 0.0, &anchors(0), anchors_da.cnt, trackGauge, wDrawColorBlack ); @@ -668,12 +695,12 @@ static paramData_t helixPLs[] = { { PD_FLOAT, &helixGrade, "grade", 0, &r0_100, N_("Grade") }, { PD_FLOAT, &helixVertSep, "vertSep", PDO_DIM, &r0_1000000, N_("Vertical Separation") }, #define I_HELIXMSG (6) - { PD_MESSAGE, N_("Total Length"), NULL, PDO_DLGRESETMARGIN, (void*)200 } }; -static paramGroup_t helixPG = { "helix", PGO_PREFMISCGROUP, helixPLs, sizeof helixPLs/sizeof helixPLs[0] }; + { PD_MESSAGE, N_("Total Length"), NULL, PDO_DLGRESETMARGIN, I2VP(200) } }; +static paramGroup_t helixPG = { "helix", PGO_PREFMISCGROUP, helixPLs, COUNT( helixPLs ) }; static paramData_t circleRadiusPLs[] = { { PD_FLOAT, &circleRadius, "radius", PDO_DIM, &r1_10000 } }; -static paramGroup_t circleRadiusPG = { "circle", 0, circleRadiusPLs, sizeof circleRadiusPLs/sizeof circleRadiusPLs[0] }; +static paramGroup_t circleRadiusPG = { "circle", 0, circleRadiusPLs, COUNT( circleRadiusPLs ) }; static void ComputeHelix( @@ -684,7 +711,7 @@ static void ComputeHelix( DIST_T totTurns; DIST_T length; long updates = 0; - if ( h_inx < 0 || h_inx >= sizeof h_orders/sizeof h_orders[0] ) + if ( h_inx < 0 || h_inx >= COUNT( h_orders ) ) return; ParamLoadData( &helixPG ); totTurns = helixTurns + helixAngSep/360.0; @@ -809,6 +836,7 @@ static STATUS_T CmdCircleCommon( wAction_t action, coOrd pos, BOOL_T helix ) break; } } + SetAllTrackSelect( FALSE ); tempSegs_da.cnt = 0; return C_CONTINUE; @@ -932,7 +960,7 @@ static STATUS_T CmdCircleCommon( wAction_t action, coOrd pos, BOOL_T helix ) static STATUS_T CmdCircle( wAction_t action, coOrd pos ) { if ( action == C_START ) { - circleMode = (long)commandContext; + circleMode = VP2L(commandContext); } return CmdCircleCommon( action, pos, FALSE ); } @@ -943,32 +971,31 @@ static STATUS_T CmdHelix( wAction_t action, coOrd pos ) return CmdCircleCommon( action, pos, TRUE ); } -#include "bitmaps/curve1.xpm" -#include "bitmaps/curve2.xpm" -#include "bitmaps/curve3.xpm" -#include "bitmaps/curve4.xpm" -#include "bitmaps/bezier.xpm" +#include "bitmaps/curved-end.xpm" +#include "bitmaps/curved-tangent.xpm" +#include "bitmaps/curved-middle.xpm" +#include "bitmaps/curved-chord.xpm" +#include "bitmaps/bezier-track.xpm" #include "bitmaps/cornu.xpm" -#include "bitmaps/circle1.xpm" -#include "bitmaps/circle2.xpm" -#include "bitmaps/circle3.xpm" +#include "bitmaps/circle.xpm" +#include "bitmaps/circle-tangent.xpm" +#include "bitmaps/circle-center.xpm" EXPORT void InitCmdCurve( wMenu_p menu ) { - AddMenuButton( menu, CmdCornu, "cmdCornu", _("Cornu Curve"), wIconCreatePixMap(cornu_xpm), LEVEL0_50, IC_STICKY|IC_POPUP2|IC_WANT_MOVE, ACCL_CORNU, (void*)cornuCmdCreateTrack); - - ButtonGroupBegin( _("Curve Track"), "cmdCircleSetCmd", _("Curve Tracks") ); - AddMenuButton( menu, CmdCurve, "cmdCurveEndPt", _("Curve from End-Pt"), wIconCreatePixMap( curve1_xpm ), LEVEL0_50, IC_STICKY|IC_POPUP2|IC_WANT_MOVE, ACCL_CURVE1, (void*)0 ); - AddMenuButton( menu, CmdCurve, "cmdCurveTangent", _("Curve from Tangent"), wIconCreatePixMap( curve2_xpm ), LEVEL0_50, IC_STICKY|IC_POPUP2|IC_WANT_MOVE, ACCL_CURVE2, (void*)1 ); - AddMenuButton( menu, CmdCurve, "cmdCurveCenter", _("Curve from Center"), wIconCreatePixMap( curve3_xpm ), LEVEL0_50, IC_STICKY|IC_POPUP2|IC_WANT_MOVE, ACCL_CURVE3, (void*)2 ); - AddMenuButton( menu, CmdCurve, "cmdCurveChord", _("Curve from Chord"), wIconCreatePixMap( curve4_xpm ), LEVEL0_50, IC_STICKY|IC_POPUP2|IC_WANT_MOVE, ACCL_CURVE4, (void*)3 ); - AddMenuButton( menu, CmdBezCurve, "cmdBezier", _("Bezier Curve"), wIconCreatePixMap(bezier_xpm), LEVEL0_50, IC_STICKY|IC_POPUP2|IC_WANT_MOVE, ACCL_BEZIER, (void*)bezCmdCreateTrack ); + ButtonGroupBegin( _("Curve Track"), "cmdCurveSetCmd", _("Curve Tracks") ); + AddMenuButton( menu, CmdCurve, "cmdCurveEndPt", _("Curve from End-Pt"), wIconCreatePixMap( curved_end_xpm[iconSize] ), LEVEL0_50, IC_STICKY|IC_POPUP2|IC_WANT_MOVE, ACCL_CURVE1, I2VP(0) ); + AddMenuButton( menu, CmdCurve, "cmdCurveTangent", _("Curve from Tangent"), wIconCreatePixMap( curved_tangent_xpm[iconSize] ), LEVEL0_50, IC_STICKY|IC_POPUP2|IC_WANT_MOVE, ACCL_CURVE2, I2VP(1) ); + AddMenuButton( menu, CmdCurve, "cmdCurveCenter", _("Curve from Center"), wIconCreatePixMap( curved_middle_xpm[iconSize] ), LEVEL0_50, IC_STICKY|IC_POPUP2|IC_WANT_MOVE, ACCL_CURVE3, I2VP(2) ); + AddMenuButton( menu, CmdCurve, "cmdCurveChord", _("Curve from Chord"), wIconCreatePixMap( curved_chord_xpm[iconSize] ), LEVEL0_50, IC_STICKY|IC_POPUP2|IC_WANT_MOVE, ACCL_CURVE4, I2VP(3) ); + AddMenuButton( menu, CmdBezCurve, "cmdBezier", _("Bezier Curve"), wIconCreatePixMap( bezier_track_xpm[iconSize] ), LEVEL0_50, IC_STICKY|IC_POPUP2|IC_WANT_MOVE, ACCL_BEZIER, I2VP(bezCmdCreateTrack) ); + AddMenuButton( menu, CmdCornu, "cmdCornu", _("Cornu Curve"), wIconCreatePixMap( cornu_xpm[iconSize] ), LEVEL0_50, IC_STICKY|IC_POPUP2|IC_WANT_MOVE, ACCL_CORNU, I2VP(cornuCmdCreateTrack)); ButtonGroupEnd(); - ButtonGroupBegin( _("Circle Track"), "cmdCurveSetCmd", _("Circle Tracks") ); - AddMenuButton( menu, CmdCircle, "cmdCircleFixedRadius", _("Fixed Radius Circle"), wIconCreatePixMap( circle1_xpm ), LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_CIRCLE1, (void*)0 ); - AddMenuButton( menu, CmdCircle, "cmdCircleTangent", _("Circle from Tangent"), wIconCreatePixMap( circle2_xpm ), LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_CIRCLE2, (void*)1 ); - AddMenuButton( menu, CmdCircle, "cmdCircleCenter", _("Circle from Center"), wIconCreatePixMap( circle3_xpm ), LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_CIRCLE3, (void*)2 ); + ButtonGroupBegin( _("Circle Track"), "cmdCircleSetCmd", _("Circle Tracks") ); + AddMenuButton( menu, CmdCircle, "cmdCircleFixedRadius", _("Fixed Radius Circle"), wIconCreatePixMap( circle_xpm[iconSize] ), LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_CIRCLE1, I2VP(0) ); + AddMenuButton( menu, CmdCircle, "cmdCircleTangent", _("Circle from Tangent"), wIconCreatePixMap( circle_tangent_xpm[iconSize] ), LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_CIRCLE2, I2VP(1) ); + AddMenuButton( menu, CmdCircle, "cmdCircleCenter", _("Circle from Center"), wIconCreatePixMap( circle_center_xpm[iconSize] ), LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_CIRCLE3, I2VP(2) ); ButtonGroupEnd(); ParamRegister( &circleRadiusPG ); |