summaryrefslogtreecommitdiff
path: root/app/bin/ccurve.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/ccurve.c')
-rw-r--r--app/bin/ccurve.c637
1 files changed, 404 insertions, 233 deletions
diff --git a/app/bin/ccurve.c b/app/bin/ccurve.c
index 58bb5c1..e119610 100644
--- a/app/bin/ccurve.c
+++ b/app/bin/ccurve.c
@@ -39,57 +39,102 @@
#include "utility.h"
#include "wlib.h"
#include "cbezier.h"
+#include "ccornu.h"
+#include "layout.h"
/*
* STATE INFO
*/
+typedef enum createState_e {NOCURVE,FIRSTEND_DEF,SECONDEND_DEF,CENTER_DEF} createState_e;
+
static struct {
STATE_T state;
+ createState_e create_state;
coOrd pos0;
coOrd pos1;
curveData_t curveData;
track_p trk;
EPINX_T ep;
BOOL_T down;
+ BOOL_T lock0;
+ coOrd middle;
+ coOrd end0;
+ coOrd end1;
} Da;
static long curveMode;
+static dynArr_t anchors_da;
+#define anchors(N) DYNARR_N(trkSeg_t,anchors_da,N)
+#define array_anchor(N) DYNARR_N(trkSeg_t,*anchor_array,N)
+
-EXPORT void DrawArrowHeads(
+EXPORT int DrawArrowHeads(
trkSeg_p sp,
coOrd pos,
ANGLE_T angle,
BOOL_T bidirectional,
wDrawColor color )
{
- coOrd p0, p1;
- DIST_T d, w;
- int inx;
- d = mainD.scale*0.25;
- w = mainD.scale/mainD.dpi*2;
- for ( inx=0; inx<5; inx++ ) {
- sp[inx].type = SEG_STRLIN;
- sp[inx].width = w;
- sp[inx].color = color;
- }
- Translate( &p0, pos, angle, d );
- Translate( &p1, pos, angle+180, bidirectional?d:(d/2.0) );
- sp[0].u.l.pos[0] = p0;
- sp[0].u.l.pos[1] = p1;
- sp[1].u.l.pos[0] = p0;
- Translate( &sp[1].u.l.pos[1], p0, angle+135, d/2.0 );
- sp[2].u.l.pos[0] = p0;
- Translate( &sp[2].u.l.pos[1], p0, angle-135, d/2.0 );
- if (bidirectional) {
- sp[3].u.l.pos[0] = p1;
- Translate( &sp[3].u.l.pos[1], p1, angle-45, d/2.0 );
- sp[4].u.l.pos[0] = p1;
- Translate( &sp[4].u.l.pos[1], p1, angle+45, d/2.0 );
- }
+ coOrd p0, p1;
+ DIST_T d, w;
+ int inx;
+ d = mainD.scale*0.25;
+ w = mainD.scale/mainD.dpi*2;
+ for ( inx=0; inx<5; inx++ ) {
+ sp[inx].type = SEG_STRLIN;
+ sp[inx].width = w;
+ sp[inx].color = color;
+ }
+ Translate( &p0, pos, angle, d );
+ Translate( &p1, pos, angle+180, bidirectional?d:(d/2.0) );
+ sp[0].u.l.pos[0] = p0;
+ sp[0].u.l.pos[1] = p1;
+ sp[1].u.l.pos[0] = p0;
+ Translate( &sp[1].u.l.pos[1], p0, angle+135, d/2.0 );
+ sp[2].u.l.pos[0] = p0;
+ Translate( &sp[2].u.l.pos[1], p0, angle-135, d/2.0 );
+ if (bidirectional) {
+ sp[3].u.l.pos[0] = p1;
+ Translate( &sp[3].u.l.pos[1], p1, angle-45, d/2.0 );
+ sp[4].u.l.pos[0] = p1;
+ Translate( &sp[4].u.l.pos[1], p1, angle+45, d/2.0 );
+ } else {
+ sp[3].u.l.pos[0] = p1;
+ sp[3].u.l.pos[1] = p1;
+ sp[4].u.l.pos[0] = p1;
+ sp[4].u.l.pos[1] = p1;
+ }
+ return 5;
}
+EXPORT int DrawArrowHeadsArray(
+ dynArr_t *anchor_array,
+ coOrd pos,
+ ANGLE_T angle,
+ BOOL_T bidirectional,
+ wDrawColor color )
+{
+ int i = (*anchor_array).cnt;
+ DYNARR_SET(trkSeg_t,*anchor_array,i+5)
+ return DrawArrowHeads(&DYNARR_N(trkSeg_t,*anchor_array,i),pos,angle,bidirectional,color);
+
+}
+
+static void CreateEndAnchor(coOrd p, dynArr_t * anchor_array, wBool_t lock) {
+ DIST_T d = tempD.scale*0.15;
+
+ DYNARR_APPEND(trkSeg_t,*anchor_array,1);
+ int i = (*anchor_array).cnt-1;
+ array_anchor(i).type = lock?SEG_FILCRCL:SEG_CRVLIN;
+ array_anchor(i).color = wDrawColorBlue;
+ array_anchor(i).u.c.center = p;
+ array_anchor(i).u.c.radius = d/2;
+ array_anchor(i).u.c.a0 = 0.0;
+ array_anchor(i).u.c.a1 = 360.0;
+ array_anchor(i).width = 0;
+}
@@ -100,6 +145,7 @@ EXPORT STATUS_T CreateCurve(
wDrawColor color,
DIST_T width,
long mode,
+ dynArr_t * anchor_array,
curveMessageProc message )
{
track_p t;
@@ -110,23 +156,28 @@ EXPORT STATUS_T CreateCurve(
switch ( action ) {
case C_START:
- DYNARR_SET( trkSeg_t, tempSegs_da, 8 );
+ DYNARR_RESET(trkSeg_t,*anchor_array);
+ DYNARR_SET( trkSeg_t, tempSegs_da, 1 );
+ Da.create_state = NOCURVE;
+ tempSegs_da.cnt = 0;
Da.down = FALSE; //Not got a valid start yet
+ Da.pos0 = zero;
+ Da.pos1 = zero;
switch ( curveMode ) {
case crvCmdFromEP1:
if (track)
- message(_("Drag from End-Point in direction of curve - Shift locks to track open end-point") );
+ message(_("Drag from endpoint in direction of curve - lock to track open endpoint") );
else
- message (_("Drag from End-Point in direction of curve") );
+ message (_("Drag from endpoint in direction of curve") );
break;
case crvCmdFromTangent:
if (track)
- message(_("Drag from End-Point to Center - Shift locks to track open end-point") );
+ message(_("Drag from endpoint to center - lock to track open endpoint") );
else
- message(_("Drag from End-Point to Center") );
+ message(_("Drag from endpoint to center") );
break;
case crvCmdFromCenter:
- message(_("Drag from Center to End-Point") );
+ message(_("Drag from center to endpoint") );
break;
case crvCmdFromChord:
message(_("Drag from one to other end of chord") );
@@ -134,6 +185,7 @@ EXPORT STATUS_T CreateCurve(
}
return C_CONTINUE;
case C_DOWN:
+ DYNARR_RESET(trkSeg_t, *anchor_array);
for ( inx=0; inx<8; inx++ ) {
tempSegs(inx).color = wDrawColorBlack;
tempSegs(inx).width = 0;
@@ -141,150 +193,212 @@ EXPORT STATUS_T CreateCurve(
tempSegs_da.cnt = 0;
p = pos;
BOOL_T found = FALSE;
- Da.trk = NULL;
- if ((mode == crvCmdFromEP1 || mode == crvCmdFromTangent) && track && (MyGetKeyState() & WKEY_SHIFT) != 0) {
- if ((t = OnTrack(&p, FALSE, TRUE)) != NULL) {
- EPINX_T ep = PickUnconnectedEndPointSilent(p, t);
- if (ep != -1) {
- Da.trk = t;
- Da.ep = ep;
- pos = GetTrkEndPos(t, ep);
- found = TRUE;
- } else {
- Da.pos0=pos;
- message(_("No unconnected end-point on track - Try again or release Shift and click"));
- return C_CONTINUE;
- }
- } else {
- Da.pos0=pos;
- message(_("Not on a track - Try again or release Shift and click"));
- return C_CONTINUE;
+ Da.trk = NULL;
+ if (track) {
+ if ((mode == crvCmdFromEP1 || mode == crvCmdFromTangent || (mode == crvCmdFromChord)) &&
+ ((MyGetKeyState() & WKEY_ALT) == 0 ) == magneticSnap) {
+ if ((t = OnTrack(&p, FALSE, TRUE)) != NULL) {
+ EPINX_T ep = PickUnconnectedEndPointSilent(p, t);
+ if (ep != -1) {
+ if (GetTrkScale(t) != (char)GetLayoutCurScale()) {
+ wBeep();
+ InfoMessage(_("Track is different gauge"));
+ return C_CONTINUE;
+ }
+ Da.trk = t;
+ Da.ep = ep;
+ pos = GetTrkEndPos(t, ep);
+ found = TRUE;
+ }
+ }
}
- Da.down = TRUE;
- }
+ } else {
+ if ((t = OnTrack(&p, FALSE, FALSE)) != NULL) {
+ if (!IsTrack(t)) {
+ pos = p;
+ found = TRUE;
+ }
+ }
+ }
Da.down = TRUE;
if (!found) SnapPos( &pos );
- pos0 = pos;
- Da.pos0 = pos;
+ Da.lock0 = found;
+
+ if (Da.create_state == NOCURVE)
+ Da.pos0 = pos;
+ else
+ Da.pos1 = pos;
+
+ tempSegs_da.cnt = 1;
switch (mode) {
case crvCmdFromEP1:
tempSegs(0).type = (track?SEG_STRTRK:SEG_STRLIN);
tempSegs(0).color = color;
tempSegs(0).width = width;
- if (Da.trk) message(_("End Locked: Drag out curve start"));
+ Da.create_state = FIRSTEND_DEF;
+ Da.end0 = pos;
+ CreateEndAnchor(pos,anchor_array,found);
+ if (Da.trk && !(MyGetKeyState() & WKEY_SHIFT)) message(_("End locked: Drag out curve start"));
+ else if (Da.trk) message(_("End Position locked: Drag out curve start with Shift"));
else message(_("Drag along curve start") );
break;
case crvCmdFromTangent:
+ Da.create_state = FIRSTEND_DEF;
+ tempSegs(0).type = SEG_STRLIN;
+ tempSegs(0).color = color;
+ Da.create_state = CENTER_DEF;
+ CreateEndAnchor(pos,anchor_array,found);
+ if (Da.trk && !(MyGetKeyState() & WKEY_SHIFT)) message(_("End locked: Drag out curve center"));
+ else if (Da.trk) message(_("End Position locked: Drag out curve start with Shift"));
+ else message(_("Drag out curve center") );
+ break;
case crvCmdFromCenter:
tempSegs(0).type = SEG_STRLIN;
- tempSegs(1).type = SEG_CRVLIN;
- tempSegs(1).u.c.radius = mainD.scale*0.05;
- tempSegs(1).u.c.a0 = 0;
- tempSegs(1).u.c.a1 = 360;
- tempSegs(2).type = SEG_STRLIN;
- if (Da.trk && mode==crvCmdFromTangent) message(_("End Locked: Drag out to center"));
- else
- message( mode==crvCmdFromTangent?_("Drag from End-Point to Center"):_("Drag from Center to End-Point") );
+ tempSegs(0).color = color;
+ Da.create_state = CENTER_DEF;
+ CreateEndAnchor(pos,anchor_array,FALSE);
+ message(_("Drag out from center to endpoint"));
break;
case crvCmdFromChord:
tempSegs(0).type = (track?SEG_STRTRK:SEG_STRLIN);
tempSegs(0).color = color;
tempSegs(0).width = width;
- message( _("Drag to other end of chord") );
+ CreateEndAnchor(pos,anchor_array,FALSE);
+ Da.create_state = FIRSTEND_DEF;
+ if (Da.trk && !(MyGetKeyState() & WKEY_SHIFT))
+ message( _("End locked: Drag to other end of chord") );
+ else if (Da.trk) message(_("End Position locked: Drag out curve start with Shift"));
+ else
+ message( _("Drag to other end of chord") );
break;
}
- tempSegs(0).u.l.pos[0] = pos;
+ tempSegs(0).u.l.pos[0] = tempSegs(0).u.l.pos[1] = pos;
return C_CONTINUE;
case C_MOVE:
+ DYNARR_RESET(trkSeg_t,*anchor_array);
+ DYNARR_APPEND(trkSeg_t,*anchor_array,1);
if (!Da.down) return C_CONTINUE;
- if (Da.trk) {
+ if (Da.trk && !(MyGetKeyState() & WKEY_SHIFT)) { //Shift inhibits direction lock
angle1 = NormalizeAngle(GetTrkEndAngle(Da.trk, Da.ep));
- angle2 = NormalizeAngle(FindAngle(pos, pos0)-angle1);
- if (mode ==crvCmdFromEP1) {
+ angle2 = NormalizeAngle(FindAngle(pos, Da.pos0)-angle1);
+ if (mode ==crvCmdFromEP1 ) {
if (angle2 > 90.0 && angle2 < 270.0)
- Translate( &pos, pos0, angle1, -FindDistance( pos0, pos )*cos(D2R(angle2)) );
- else pos = pos0;
- } else {
- DIST_T dp = -FindDistance(pos0, pos)*sin(D2R(angle2));
- if (angle2 > 180.0)
- Translate( &pos, pos0, angle1+90.0, dp );
+ Translate( &pos, Da.pos0, angle1, -FindDistance( Da.pos0, pos )*cos(D2R(angle2)) );
+ else pos = Da.pos0;
+ } else if ( mode == crvCmdFromChord ) {
+ DIST_T dp = -FindDistance(Da.pos0, pos)*sin(D2R(angle2));
+ if (DifferenceBetweenAngles(FindAngle(Da.pos0,pos),angle1)>0)
+ Translate( &pos, Da.pos0, angle1+90, dp );
+ else
+ Translate( &pos, Da.pos0, angle1-90, -dp );
+ } else if (mode == crvCmdFromCenter) {
+ DIST_T dp = -FindDistance(Da.pos0, pos)*sin(D2R(angle2));
+ if (angle2 > 90 && angle2 < 270.0)
+ Translate( &pos, Da.pos0, angle1+90.0, dp );
else
- Translate( &pos, pos0, angle1-90.0, dp );
+ Translate( &pos, Da.pos0, angle1-90.0, dp );
+ } else if (mode == crvCmdFromTangent) {
+ DIST_T dp = FindDistance(Da.pos0, pos)*sin(D2R(angle2));
+ Translate( &pos, Da.pos0, angle1-90.0, dp );
}
} else SnapPos(&pos);
- tempSegs(0).u.l.pos[1] = pos;
- d = FindDistance( pos0, pos );
- a = FindAngle( pos0, pos );
+ tempSegs_da.cnt =1;
+ if (Da.trk && mode == crvCmdFromChord) {
+ tempSegs(0).type = SEG_CRVTRK;
+ tempSegs(0).u.c.center.x = (pos.x+Da.pos0.x)/2.0;
+ tempSegs(0).u.c.center.y = (pos.y+Da.pos0.y)/2.0;
+ tempSegs(0).u.c.radius = FindDistance(pos,Da.pos0)/2;
+ ANGLE_T a0 = FindAngle(tempSegs(0).u.c.center,Da.pos0);
+ ANGLE_T a1 = FindAngle(tempSegs(0).u.c.center,pos);
+ if (NormalizeAngle(a0+90-GetTrkEndAngle(Da.trk,Da.ep))<90) {
+ tempSegs(0).u.c.a0 = a0;
+ } else {
+ tempSegs(0).u.c.a0 = a1;
+ }
+ tempSegs(0).u.c.a1 = 180.0;
+ } else tempSegs(0).u.l.pos[1] = pos;
+ Da.pos1 = pos;
+
+ d = FindDistance( Da.pos0, Da.pos1 );
+ a = FindAngle( Da.pos0, Da.pos1 );
switch ( mode ) {
case crvCmdFromEP1:
if (Da.trk) message( _("Start Locked: Drag out curve start - Angle=%0.3f"), PutAngle(a));
else message( _("Drag out curve start - Angle=%0.3f"), PutAngle(a) );
+ CreateEndAnchor(Da.pos0,anchor_array,Da.lock0);
+ DrawArrowHeadsArray( anchor_array, pos, FindAngle(Da.pos0,Da.pos1)+90, TRUE, wDrawColorBlue );
tempSegs_da.cnt = 1;
break;
case crvCmdFromTangent:
- if (Da.trk) message( _("Tangent Locked: Drag out center - Radius=%s Angle=%0.3f"), FormatDistance(d), PutAngle(a) );
+ if (Da.trk) message( _("Tangent locked: Drag out center - Radius=%s Angle=%0.3f"), FormatDistance(d), PutAngle(a) );
else message( _("Drag out center - Radius=%s Angle=%0.3f"), FormatDistance(d), PutAngle(a) );
- tempSegs(1).u.c.center = pos;
- DrawArrowHeads( &tempSegs(2), pos0, FindAngle(pos0,pos)+90, TRUE, wDrawColorBlack );
- tempSegs_da.cnt = 7;
+ CreateEndAnchor(Da.pos1,anchor_array,TRUE);
+ DrawArrowHeadsArray( anchor_array, Da.pos0, FindAngle(Da.pos0,Da.pos1)+90, TRUE, wDrawColorBlue );
+ tempSegs_da.cnt = 1;
break;
case crvCmdFromCenter:
- message( _("Radius=%s Angle=%0.3f"), FormatDistance(d), PutAngle(a) );
- tempSegs(1).u.c.center = pos0;
- DrawArrowHeads( &tempSegs(2), pos, FindAngle(pos,pos0)+90, TRUE, wDrawColorBlack );
- tempSegs_da.cnt = 7;
+ message( _("Drag to Edge: Radius=%s Angle=%0.3f"), FormatDistance(d), PutAngle(a) );
+ CreateEndAnchor(Da.pos0,anchor_array,Da.lock0);
+ DrawArrowHeadsArray( anchor_array, Da.pos1, FindAngle(Da.pos1,Da.pos0)+90, TRUE, wDrawColorBlue );
+ tempSegs_da.cnt = 1;
break;
case crvCmdFromChord:
- message( _("Length=%s Angle=%0.3f"), FormatDistance(d), PutAngle(a) );
- if ( d > mainD.scale*0.25 ) {
- pos.x = (pos.x+pos0.x)/2.0;
- pos.y = (pos.y+pos0.y)/2.0;
- DrawArrowHeads( &tempSegs(1), pos, FindAngle(pos,pos0)+90, TRUE, wDrawColorBlack );
- tempSegs_da.cnt = 6;
- } else {
- tempSegs_da.cnt = 1;
+ if (Da.trk) message( _("Start locked: Drag out chord length=%s angle=%0.3f"), FormatDistance(d), PutAngle(a) );
+ else message( _("Drag out chord length=%s angle=%0.3f"), FormatDistance(d), PutAngle(a) );
+ Da.middle.x = (Da.pos1.x+Da.pos0.x)/2.0;
+ Da.middle.y = (Da.pos1.y+Da.pos0.y)/2.0;
+ if (track && Da.trk) {
+ ANGLE_T ea = GetTrkEndAngle(Da.trk,Da.ep);
+ Translate(&Da.middle,Da.middle,ea,FindDistance(Da.middle,Da.pos0));
}
+ CreateEndAnchor(Da.pos0,anchor_array,TRUE);
+ CreateEndAnchor(Da.pos1,anchor_array,FALSE);
+ if (!track || !Da.trk)
+ DrawArrowHeadsArray( anchor_array, Da.middle, FindAngle(Da.pos0,Da.pos1)+90, TRUE, wDrawColorBlue );
break;
}
return C_CONTINUE;
case C_UP:
+ /* Note - no anchor reset - assumes run after Down/Move */
if (!Da.down) return C_CONTINUE;
if (Da.trk) {
angle1 = NormalizeAngle(GetTrkEndAngle(Da.trk, Da.ep));
- angle2 = NormalizeAngle(FindAngle(pos, pos0)-angle1);
+ angle2 = NormalizeAngle(FindAngle(pos, Da.pos0)-angle1);
if (mode == crvCmdFromEP1) {
if (angle2 > 90.0 && angle2 < 270.0) {
- Translate( &pos, pos0, angle1, -FindDistance( pos0, pos )*cos(D2R(angle2)) );
+ Translate( &pos, Da.pos0, angle1, -FindDistance( Da.pos0, pos )*cos(D2R(angle2)) );
Da.pos1 = pos;
} else {
ErrorMessage( MSG_TRK_TOO_SHORT, "Curved ", PutDim(0.0) );
return C_TERMINATE;
}
+ } else if (mode == crvCmdFromTangent) {
+ DIST_T dp = FindDistance(Da.pos0, pos)*sin(D2R(angle2));
+ Translate( &pos, Da.pos0, angle1-90.0, dp );
+ Da.pos1 = pos;
} else {
- DIST_T dp = -FindDistance(pos0, pos)*sin(D2R(angle2));
+ DIST_T dp = -FindDistance(Da.pos0, pos)*sin(D2R(angle2));
if (angle2 > 180.0)
- Translate( &pos, pos0, angle1+90.0, dp );
+ Translate( &pos, Da.pos0, angle1+90.0, dp );
else
- Translate( &pos, pos0, angle1-90.0, dp );
+ Translate( &pos, Da.pos0, angle1-90.0, dp );
Da.pos1 = pos;
}
+ if (FindDistance(Da.pos0,Da.pos1)<minLength) {
+ ErrorMessage( MSG_TRK_TOO_SHORT, "Curved ", PutDim(FindDistance(Da.pos0,Da.pos1)) );
+ return C_TERMINATE;
+ }
}
switch (mode) {
case crvCmdFromEP1:
- DrawArrowHeads( &tempSegs(1), pos, FindAngle(pos,pos0)+90, TRUE, drawColorRed );
- tempSegs_da.cnt = 6;
- break;
- case crvCmdFromChord:
- tempSegs(1).color = drawColorRed;
case crvCmdFromTangent:
case crvCmdFromCenter:
- tempSegs(2).color = drawColorRed;
- tempSegs(3).color = drawColorRed;
- tempSegs(4).color = drawColorRed;
- tempSegs(5).color = drawColorRed;
- tempSegs(6).color = drawColorRed;
- break;
+ case crvCmdFromChord:
+ for (int i=0;i<(*anchor_array).cnt;i++) {
+ DYNARR_N(trkSeg_t,*anchor_array,i).color = drawColorRed;
+ }
+ break;
}
message( _("Drag on Red arrows to adjust curve") );
return C_CONTINUE;
@@ -296,6 +410,7 @@ EXPORT STATUS_T CreateCurve(
}
+
static STATUS_T CmdCurve( wAction_t action, coOrd pos )
{
track_p t;
@@ -310,38 +425,71 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos )
Da.state = -1;
Da.pos0 = pos;
tempSegs_da.cnt = 0;
+ segCnt = 0;
STATUS_T rcode;
- return CreateCurve( action, pos, TRUE, wDrawColorBlack, 0, curveMode, InfoMessage );
-
- case C_TEXT:
- if ( Da.state == 0 )
- return CreateCurve( action, pos, TRUE, wDrawColorBlack, 0, curveMode, InfoMessage );
- else
- return C_CONTINUE;
+ DYNARR_RESET(trkSeg_t,anchors_da);
+ return CreateCurve( action, pos, TRUE, wDrawColorBlack, 0, curveMode, &anchors_da, InfoMessage );
case C_DOWN:
- if ( Da.state == -1 ) {
- //SnapPos( &pos );
- Da.pos0 = pos;
+ 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 );
+ Da.pos0 = Da.pos1 = pos;
Da.state = 0;
- rcode = CreateCurve( action, pos, TRUE, wDrawColorBlack, 0, curveMode, InfoMessage );
+ rcode = CreateCurve( action, pos, TRUE, wDrawColorBlack, 0, curveMode, &anchors_da, InfoMessage );
+ segCnt = tempSegs_da.cnt ;
if (!Da.down) Da.state = -1;
return rcode;
//Da.pos0 = pos;
- } else {
- tempSegs_da.cnt = segCnt;
- return C_CONTINUE;
}
+ //This is where the user could adjust - if we allow that?
+ tempSegs_da.cnt = segCnt;
+ return C_CONTINUE;
+
+
+ case wActionMove:
+ if ((Da.state<0) && (curveMode != crvCmdFromCenter)) {
+ DYNARR_RESET(trkSeg_t,anchors_da);
+ if (((MyGetKeyState() & WKEY_ALT)==0) == magneticSnap) {
+ if ((t=OnTrack(&pos,FALSE,TRUE))!= NULL) {
+ if (GetTrkGauge(t) == GetScaleTrackGauge(GetLayoutCurScale())) {
+ EPINX_T ep = PickUnconnectedEndPointSilent(pos, t);
+ if (ep != -1) {
+ pos = GetTrkEndPos(t, ep);
+ CreateEndAnchor(pos,&anchors_da,FALSE);
+ }
+ }
+ }
+ }
+ }
+ return C_CONTINUE;
case C_MOVE:
if (Da.state<0) return C_CONTINUE;
- mainD.funcs->options = wDrawOptTemp;
- DrawSegs( &mainD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
if ( Da.state == 0 ) {
Da.pos1 = pos;
- rc = CreateCurve( action, pos, TRUE, wDrawColorBlack, 0, curveMode, InfoMessage );
+ rc = CreateCurve( action, pos, TRUE, wDrawColorBlack, 0, curveMode, &anchors_da, InfoMessage );
+ segCnt = tempSegs_da.cnt ;
} else {
+ 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.curveData.type == curveTypeStraight) {
@@ -349,11 +497,14 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos )
tempSegs(0).u.l.pos[0] = Da.pos0;
tempSegs(0).u.l.pos[1] = Da.curveData.pos1;
tempSegs_da.cnt = 1;
+ segCnt = 1;
InfoMessage( _("Straight Track: Length=%s Angle=%0.3f"),
FormatDistance(FindDistance( Da.pos0, Da.curveData.pos1 )),
PutAngle(FindAngle( Da.pos0, Da.curveData.pos1 )) );
+ DrawArrowHeadsArray(&anchors_da,Da.curveData.pos1,FindAngle(Da.pos0, Da.curveData.pos1)+90,TRUE,wDrawColorRed);
} else if (Da.curveData.type == curveTypeNone) {
tempSegs_da.cnt = 0;
+ segCnt = 0;
InfoMessage( _("Back") );
} else if (Da.curveData.type == curveTypeCurve) {
tempSegs(0).type = SEG_CRVTRK;
@@ -362,6 +513,7 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos )
tempSegs(0).u.c.a0 = Da.curveData.a0;
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;
@@ -375,80 +527,101 @@ static STATUS_T CmdCurve( wAction_t action, coOrd pos )
InfoMessage( _("Curved Track: Radius=%s Angle=%0.3f Length=%s"),
FormatDistance(Da.curveData.curveRadius), Da.curveData.a1,
FormatDistance(Da.curveData.curveRadius*d) );
+ coOrd pos1;
+ Translate(&pos1,Da.curveData.curvePos,Da.curveData.a0+Da.curveData.a1,Da.curveData.curveRadius);
+ 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);
+ DrawArrowHeadsArray(&anchors_da,Da.curveData.pos2,FindAngle(Da.curveData.curvePos,Da.curveData.pos2)+90,TRUE,wDrawColorRed);
+ }
+ CreateEndAnchor(Da.curveData.curvePos,&anchors_da,TRUE);
}
}
- DrawSegs( &mainD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
mainD.funcs->options = 0;
return rc;
-
-
+ case C_TEXT:
+ if ( Da.state == 0 )
+ return CreateCurve( action, pos, TRUE, wDrawColorBlack, 0, curveMode, &anchors_da, InfoMessage );
+ /*no break*/
case C_UP:
if (Da.state<0) return C_CONTINUE;
- mainD.funcs->options = wDrawOptTemp;
- DrawSegs( &mainD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
- if (Da.state == 0) {
+ if (Da.state == 0 && ((curveMode != crvCmdFromChord) || (curveMode == crvCmdFromChord && !Da.trk))) {
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;
+ }
Da.state = 1;
- CreateCurve( action, pos, TRUE, wDrawColorBlack, 0, curveMode, InfoMessage );
- DrawSegs( &mainD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
+ 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") );
return C_CONTINUE;
- } else {
- mainD.funcs->options = 0;
- tempSegs_da.cnt = 0;
- Da.state = -1;
- if (Da.curveData.type == curveTypeStraight) {
- if ((d=FindDistance( Da.pos0, Da.curveData.pos1 )) <= minLength) {
- ErrorMessage( MSG_TRK_TOO_SHORT, "Curved ", PutDim(fabs(minLength-d)) );
- return C_TERMINATE;
- }
- UndoStart( _("Create Straight Track"), "newCurve - straight" );
- t = NewStraightTrack( Da.pos0, Da.curveData.pos1 );
- if (Da.trk) {
- EPINX_T ep = PickUnconnectedEndPoint(Da.pos0, t);
- if (ep != -1) ConnectTracks(Da.trk, Da.ep, t, ep);
- }
- UndoEnd();
- } else if (Da.curveData.type == curveTypeCurve) {
- if ((d= Da.curveData.curveRadius * Da.curveData.a1 *2.0*M_PI/360.0) <= minLength) {
- 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 );
- if (Da.trk) {
- EPINX_T ep = PickUnconnectedEndPoint(Da.pos0, t);
- if (ep != -1) ConnectTracks(Da.trk, Da.ep, t, ep);
- }
- UndoEnd();
- } else {
- return C_ERROR;
+ } else if ((curveMode == crvCmdFromChord && Da.state == 0 && Da.trk)) {
+ pos = Da.middle;
+ if ((d = FindDistance(Da.pos0,Da.pos1))<minLength) {
+ ErrorMessage( MSG_TRK_TOO_SHORT, "Curved ", PutDim(fabs(minLength-d)) );
+ return C_TERMINATE;
+ }
+ PlotCurve( curveMode, Da.pos0, Da.pos1, Da.middle, &Da.curveData, TRUE );
+ }
+ mainD.funcs->options = 0;
+ tempSegs_da.cnt = 0;
+ segCnt = 0;
+ Da.state = -1;
+ DYNARR_RESET(trkSeg_t,anchors_da); // No More anchors for this one
+ if (Da.curveData.type == curveTypeStraight) {
+ if ((d = FindDistance( Da.pos0, Da.curveData.pos1 )) < minLength) {
+ ErrorMessage( MSG_TRK_TOO_SHORT, "Curved ", PutDim(fabs(minLength-d)) );
+ return C_TERMINATE;
+ }
+ UndoStart( _("Create Straight Track"), "newCurve - straight" );
+ t = NewStraightTrack( Da.pos0, Da.curveData.pos1 );
+ if (Da.trk && !(MyGetKeyState() & WKEY_SHIFT)) {
+ EPINX_T ep = PickUnconnectedEndPoint(Da.pos0, t);
+ if (ep != -1) ConnectTracks(Da.trk, Da.ep, t, ep);
+ }
+ UndoEnd();
+ } else if (Da.curveData.type == curveTypeCurve) {
+ if ((d = Da.curveData.curveRadius * Da.curveData.a1 *2.0*M_PI/360.0) < minLength) {
+ 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 );
+ if (Da.trk && !(MyGetKeyState() & WKEY_SHIFT)) {
+ EPINX_T ep = PickUnconnectedEndPoint(Da.pos0, t);
+ if (ep != -1) ConnectTracks(Da.trk, Da.ep, t, ep);
}
- DrawNewTrack( t );
- return C_TERMINATE;
+ UndoEnd();
+ } else {
+ return C_ERROR;
}
+ DrawNewTrack( t );
+ return C_TERMINATE;
case C_REDRAW:
if ( Da.state >= 0 ) {
- mainD.funcs->options = wDrawOptTemp;
- DrawSegs( &mainD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
+ 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 );
return C_CONTINUE;
case C_CANCEL:
if (Da.state == 1) {
- mainD.funcs->options = wDrawOptTemp;
- DrawSegs( &mainD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
- mainD.funcs->options = 0;
tempSegs_da.cnt = 0;
Da.trk = NULL;
}
+ DYNARR_RESET(trkSeg_t,anchors_da);
+ DYNARR_RESET(trkSeg_t,tempSegs_da);
Da.state = -1;
+ segCnt = 0;
return C_CONTINUE;
}
@@ -581,7 +754,6 @@ static void ComputeHelix(
static void HelixCancel( wWin_p win )
{
wHide( helixW );
- Reset();
}
@@ -610,30 +782,30 @@ static STATUS_T CmdCircleCommon( wAction_t action, coOrd pos, BOOL_T helix )
case C_START:
if (helix) {
if (helixW == NULL)
- helixW = ParamCreateDialog( &helixPG, MakeWindowTitle(_("Helix")), NULL, NULL, HelixCancel, TRUE, NULL, 0, ComputeHelix );
- ParamLoadControls( &helixPG );
- ParamGroupRecord( &helixPG );
- ComputeHelix( NULL, 6, NULL );
- wShow( helixW );
- memset( h_orders, 0, sizeof h_orders );
+ helixW = ParamCreateDialog(&helixPG, MakeWindowTitle(_("Helix")), NULL, NULL, HelixCancel, TRUE, NULL, 0, ComputeHelix);
+ ParamLoadControls(&helixPG);
+ ParamGroupRecord(&helixPG);
+ ComputeHelix(NULL, 6, NULL);
+ wShow(helixW);
+ memset(h_orders, 0, sizeof h_orders);
h_clock = 0;
} else {
- ParamLoadControls( &circleRadiusPG );
- ParamGroupRecord( &circleRadiusPG );
- switch ( circleMode ) {
+ ParamLoadControls(&circleRadiusPG);
+ ParamGroupRecord(&circleRadiusPG);
+ switch (circleMode) {
case circleCmdFixedRadius:
controls[0] = circleRadiusPLs[0].control;
controls[1] = NULL;
labels[0] = N_("Circle Radius");
- InfoSubstituteControls( controls, labels );
+ InfoSubstituteControls(controls, labels);
break;
case circleCmdFromTangent:
- InfoSubstituteControls( NULL, NULL );
- InfoMessage( _("Click on Circle Edge") );
+ InfoSubstituteControls(NULL, NULL);
+ InfoMessage(_("Click on Circle Edge"));
break;
case circleCmdFromCenter:
- InfoSubstituteControls( NULL, NULL );
- InfoMessage( _("Click on Circle Center") );
+ InfoSubstituteControls(NULL, NULL);
+ InfoMessage(_("Click on Circle Center"));
break;
}
}
@@ -641,98 +813,95 @@ static STATUS_T CmdCircleCommon( wAction_t action, coOrd pos, BOOL_T helix )
return C_CONTINUE;
case C_DOWN:
- DYNARR_SET( trkSeg_t, tempSegs_da, 1 );
+ DYNARR_SET(trkSeg_t, tempSegs_da, 1);
tempSegs_da.cnt = 0;
if (helix) {
if (helixRadius <= 0.0) {
- ErrorMessage( MSG_RADIUS_GTR_0 );
+ ErrorMessage(MSG_RADIUS_GTR_0);
return C_ERROR;
}
if (helixTurns <= 0) {
- ErrorMessage( MSG_HELIX_TURNS_GTR_0 );
+ ErrorMessage(MSG_HELIX_TURNS_GTR_0);
return C_ERROR;
}
- ParamLoadData( &helixPG );
+ ParamLoadData(&helixPG);
} else {
- ParamLoadData( &circleRadiusPG );
- switch( circleMode ) {
+ ParamLoadData(&circleRadiusPG);
+ switch (circleMode) {
case circleCmdFixedRadius:
if (circleRadius <= 0.0) {
- ErrorMessage( MSG_RADIUS_GTR_0 );
+ ErrorMessage(MSG_RADIUS_GTR_0);
return C_ERROR;
}
break;
case circleCmdFromTangent:
- InfoSubstituteControls( NULL, NULL );
- InfoMessage( _("Drag to Center") );
+ InfoSubstituteControls(NULL, NULL);
+ InfoMessage(_("Drag to Center"));
break;
case circleCmdFromCenter:
- InfoSubstituteControls( NULL, NULL );
- InfoMessage( _("Drag to Edge") );
+ InfoSubstituteControls(NULL, NULL);
+ InfoMessage(_("Drag to Edge"));
break;
}
}
- SnapPos( &pos );
+ SnapPos(&pos);
tempSegs(0).u.c.center = pos0 = pos;
tempSegs(0).color = wDrawColorBlack;
tempSegs(0).width = 0;
return C_CONTINUE;
case C_MOVE:
- DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
- SnapPos( &pos );
+ SnapPos(&pos);
tempSegs(0).u.c.center = pos;
- if ( !helix ) {
- switch ( circleMode ) {
+ if (!helix) {
+ switch (circleMode) {
case circleCmdFixedRadius:
break;
case circleCmdFromCenter:
tempSegs(0).u.c.center = pos0;
- circleRadius = FindDistance( tempSegs(0).u.c.center, pos );
- InfoMessage( _("Radius=%s"), FormatDistance(circleRadius) );
+ circleRadius = FindDistance(tempSegs(0).u.c.center, pos);
+ InfoMessage(_("Radius=%s"), FormatDistance(circleRadius));
break;
case circleCmdFromTangent:
- circleRadius = FindDistance( tempSegs(0).u.c.center, pos0 );
- InfoMessage( _("Radius=%s"), FormatDistance(circleRadius) );
+ circleRadius = FindDistance(tempSegs(0).u.c.center, pos0);
+ InfoMessage(_("Radius=%s"), FormatDistance(circleRadius));
break;
}
}
tempSegs(0).type = SEG_CRVTRK;
- tempSegs(0).u.c.radius = helix?helixRadius:circleRadius;
+ tempSegs(0).u.c.radius = helix ? helixRadius : circleRadius;
tempSegs(0).u.c.a0 = 0.0;
tempSegs(0).u.c.a1 = 360.0;
tempSegs_da.cnt = 1;
- DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
return C_CONTINUE;
case C_UP:
- DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );
- if (helixRadius > mapD.size.x && helixRadius > mapD.size.y) {
- ErrorMessage( MSG_RADIUS_TOO_BIG );
- return C_ERROR;
- }
- if (circleRadius > mapD.size.x && circleRadius > mapD.size.y) {
- ErrorMessage( MSG_RADIUS_TOO_BIG );
- return C_ERROR;
- }
- if ( helix ) {
+ if (helix) {
+ if (helixRadius > mapD.size.x || helixRadius > mapD.size.y) {
+ ErrorMessage(MSG_RADIUS_TOO_BIG);
+ return C_ERROR;
+ }
if (helixRadius > 10000) {
- ErrorMessage( MSG_RADIUS_GTR_10000 );
+ ErrorMessage(MSG_RADIUS_GTR_10000);
return C_ERROR;
}
- UndoStart( _("Create Helix Track"), "newHelix" );
- t = NewCurvedTrack( tempSegs(0).u.c.center, helixRadius, 0.0, 0.0, helixTurns );
+ UndoStart(_("Create Helix Track"), "newHelix");
+ t = NewCurvedTrack(tempSegs(0).u.c.center, helixRadius, 0.0, 0.0, helixTurns);
} else {
- if ( circleRadius <= 0 ) {
- ErrorMessage( MSG_RADIUS_GTR_0 );
+ if (circleRadius > mapD.size.x || circleRadius > mapD.size.y) {
+ ErrorMessage(MSG_RADIUS_TOO_BIG);
+ return C_ERROR;
+ }
+ if (circleRadius <= 0) {
+ ErrorMessage(MSG_RADIUS_GTR_0);
return C_ERROR;
}
if ((circleRadius > 100000) || (helixRadius > 10000)) {
- ErrorMessage( MSG_RADIUS_GTR_10000 );
+ ErrorMessage(MSG_RADIUS_GTR_10000);
return C_ERROR;
}
- UndoStart( _("Create Circle Track"), "newCircle" );
- t = NewCurvedTrack( tempSegs(0).u.c.center, circleRadius, 0.0, 0.0, 0 );
+ UndoStart(_("Create Circle Track"), "newCircle");
+ t = NewCurvedTrack(tempSegs(0).u.c.center, circleRadius, 0.0, 0.0, 0);
}
UndoEnd();
DrawNewTrack(t);
@@ -779,19 +948,21 @@ static STATUS_T CmdHelix( wAction_t action, coOrd pos )
#include "bitmaps/curve3.xpm"
#include "bitmaps/curve4.xpm"
#include "bitmaps/bezier.xpm"
+#include "bitmaps/cornu.xpm"
#include "bitmaps/circle1.xpm"
#include "bitmaps/circle2.xpm"
#include "bitmaps/circle3.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, ACCL_CURVE1, (void*)0 );
- AddMenuButton( menu, CmdCurve, "cmdCurveTangent", _("Curve from Tangent"), wIconCreatePixMap( curve2_xpm ), LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_CURVE2, (void*)1 );
- AddMenuButton( menu, CmdCurve, "cmdCurveCenter", _("Curve from Center"), wIconCreatePixMap( curve3_xpm ), LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_CURVE3, (void*)2 );
- AddMenuButton( menu, CmdCurve, "cmdCurveChord", _("Curve from Chord"), wIconCreatePixMap( curve4_xpm ), LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_CURVE4, (void*)3 );
- AddMenuButton( menu, CmdBezCurve, "cmdBezier", _("Bezier Curve"), wIconCreatePixMap(bezier_xpm), LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_BEZIER, (void*)bezCmdCreateTrack );
+ 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 );
ButtonGroupEnd();
ButtonGroupBegin( _("Circle Track"), "cmdCurveSetCmd", _("Circle Tracks") );
@@ -816,7 +987,7 @@ EXPORT void InitCmdCurve( wMenu_p menu )
void InitCmdHelix(wMenu_p menu)
{
AddMenuButton(menu, CmdHelix, "cmdHelix", _("Helix"), NULL, LEVEL0_50,
- IC_STICKY|IC_POPUP2, ACCL_HELIX, NULL);
+ IC_STICKY|IC_INITNOTSTICKY|IC_POPUP2, ACCL_HELIX, NULL);
ParamRegister(&helixPG);
RegisterChangeNotification(ChangeHelixW);
}