diff options
Diffstat (limited to 'app/bin/drawgeom.c')
-rw-r--r-- | app/bin/drawgeom.c | 504 |
1 files changed, 321 insertions, 183 deletions
diff --git a/app/bin/drawgeom.c b/app/bin/drawgeom.c index d23031f..f249ff0 100644 --- a/app/bin/drawgeom.c +++ b/app/bin/drawgeom.c @@ -17,21 +17,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <math.h> -#include <stdarg.h> -#include <string.h> - #include "ccurve.h" #include "cbezier.h" #include "compound.h" #include "cundo.h" #include "drawgeom.h" #include "fileio.h" -#include "i18n.h" -#include "messages.h" #include "param.h" #include "track.h" -#include "utility.h" +#include "common-ui.h" static long drawGeomCurveMode; @@ -81,14 +75,15 @@ static void EndPoly( drawContext_t * context, int cnt, wBool_t open) -static void DrawGeomOk( void ) +static void DrawGeomOk( BOOL_T started ) { track_p trk; int inx; if (tempSegs_da.cnt <= 0) return; - UndoStart( _("Create Lines"), "newDraw" ); + if (!started) + UndoStart( _("Create Lines"), "newDraw" ); for ( inx=0; inx<tempSegs_da.cnt; inx++ ) { trk = MakeDrawFromSeg( zero, 0.0, &tempSegs(inx) ); DrawNewTrack( trk ); @@ -150,7 +145,7 @@ static void CreateSquareAnchor(coOrd p) { BOOL_T FindTempNear(drawContext_t *context, coOrd *p) { if (context->State == 2) { - if (context->Op >= OP_CURVE1 && context->Op <= OP_CURVE4) { + if ((context->Op >= OP_CURVE1) && (context->Op <= OP_CURVE4)) { if (context->ArcData.type == curveTypeCurve) { ANGLE_T a = FindAngle(context->ArcData.curvePos,*p); if (IsClose(FindDistance(context->ArcData.curvePos,*p)-context->ArcData.curveRadius) && @@ -162,7 +157,7 @@ BOOL_T FindTempNear(drawContext_t *context, coOrd *p) { if (IsClose(LineDistance(p,tempSegs(0).u.l.pos[0],tempSegs(0).u.l.pos[1]))) return TRUE; } - } else if ( context->Op >=OP_LINE && context->Op <= OP_BENCH) { + } else if ( (context->Op >=OP_LINE) && (context->Op <= OP_BENCH)) { if (IsClose(LineDistance(p,tempSegs(0).u.l.pos[0],tempSegs(0).u.l.pos[1]))) return TRUE; } @@ -190,8 +185,8 @@ STATUS_T DrawGeomMouse( drawContext_t *context) { static int lastValid = FALSE; - static wBool_t lock; - static coOrd pos0, pos0x, pos1, lastPos; + static BOOL_T locked; + static coOrd pos0, pos0x, pos1, lastPos, movePos; trkSeg_p segPtr; pts_t *pts; int inx; @@ -275,6 +270,7 @@ STATUS_T DrawGeomMouse( default: break; } + context->Changed = TRUE; //Update made MainRedraw(); anchors_da.cnt = 0; return C_CONTINUE; @@ -286,41 +282,67 @@ STATUS_T DrawGeomMouse( CleanSegs(&tempSegs_da); DYNARR_RESET( trkSeg_t, tempSegs_da ); DYNARR_RESET( trkSeg_t, anchors_da ); - lock = FALSE; + locked = FALSE; if (!magneticSnap) - InfoMessage(_("+Shift to lock to nearby objects")); + InfoMessage(_("+Alt for Magnetic Snap")); else - InfoMessage(_("+Shift to not lock to nearby objects")); + InfoMessage(_("+Alt to inhibit Magnetic Snap")); + wSetCursor(mainD.d,defaultCursor); + movePos = zero; + context->UndoStarted = FALSE; return C_CONTINUE; case wActionMove: - if (context->State == 0 || context->State ==2 ) { + locked = FALSE; + wSetCursor(mainD.d,defaultCursor); + if ((context->State == 0 && + context->Op != OP_FILLCIRCLE2 && context->Op != OP_CIRCLE2) || + context->State ==2 || + (context->State == 1 && + (context->Op == OP_POLY || context->Op == OP_FILLPOLY || context->Op == OP_POLYLINE))) { DYNARR_RESET( trkSeg_t, anchors_da ); - switch (context->Op) { //Snap pos to nearest line if this is end and just shift is depressed for lines and some curves + wSetCursor(mainD.d,defaultCursor); + switch (context->Op) { //Snap pos to nearest line for lines and some curves case OP_CURVE1: case OP_CURVE2: case OP_CURVE3: case OP_CURVE4: + case OP_CIRCLE2: + case OP_CIRCLE3: + case OP_FILLCIRCLE2: + case OP_FILLCIRCLE3: case OP_LINE: case OP_DIMLINE: case OP_BENCH: + case OP_TBLEDGE: + case OP_BOX: + case OP_FILLBOX: case OP_POLY: case OP_FILLPOLY: - case OP_POLYLINE: - if (((MyGetKeyState() & WKEY_ALT) == 0) == magneticSnap ) { + case OP_POLYLINE:; + if (((MyGetKeyState() & WKEY_ALT)==0) == magneticSnap ) { coOrd p = pos; track_p t; - if ((t=OnTrack(&p,FALSE,FALSE))!=NULL) { + if (((t=OnTrack(&p,FALSE,FALSE))!=NULL) && (IsClose(FindDistance(p,pos))) ) { if (context->Op == OP_DIMLINE ) { CreateEndAnchor(p,FALSE); - } else if (!IsTrack(t)) CreateEndAnchor(p,FALSE); - } else { - p = pos; - if (FindTempNear(context,&p)) { + wSetCursor(mainD.d,wCursorNone); + movePos = p; + locked = TRUE; + } else if (!IsTrack(t)) { CreateEndAnchor(p,FALSE); + wSetCursor(mainD.d,wCursorNone); + movePos = p; + locked = TRUE; } } } + if (!locked && SnapPos(&pos)) { + CreateEndAnchor(pos,FALSE); + wSetCursor(mainD.d,wCursorNone); + movePos = pos; + locked = TRUE; + } break; default: ; @@ -328,18 +350,22 @@ STATUS_T DrawGeomMouse( } return C_CONTINUE; + case wActionRDown: case wActionLDown: DYNARR_RESET( trkSeg_t, anchors_da ); + wSetCursor(mainD.d,defaultCursor); if (context->State == 2) { tempSegs_da.cnt = segCnt; if ((context->Op == OP_POLY || context->Op == OP_FILLPOLY || context->Op == OP_POLYLINE)) { EndPoly(context, segCnt, context->Op==OP_POLYLINE); } else { - DrawGeomOk(); + DrawGeomOk(TRUE); } + context->UndoStarted = FALSE; segCnt = 0; anchors_da.cnt = 0; context->State = 0; + TryCheckPoint(); } context->Started = TRUE; line_angle = 90.0; @@ -347,22 +373,15 @@ STATUS_T DrawGeomMouse( (context->Op == OP_CURVE2 && context->State == 0) || (context->Op == OP_CURVE3 && context->State != 0) || (context->Op == OP_CURVE4 && context->State != 2) || + (context->Op == OP_CIRCLE2 && context->State != 0) || + (context->Op == OP_CIRCLE3 && context->State == 0) || + (context->Op == OP_FILLCIRCLE2 && context->State != 0) || + (context->Op == OP_FILLCIRCLE3 && context->State == 0) || (context->Op == OP_LINE) || (context->Op == OP_DIMLINE) || - (context->Op == OP_BENCH) ) { - BOOL_T found = FALSE; - if (((MyGetKeyState() & WKEY_ALT) ==0) == magneticSnap ) { - coOrd p = pos; - track_p t; - if ((t=OnTrack(&p,FALSE,FALSE))!=NULL) { - if (!IsTrack(t)) { - EPINX_T ep1,ep2; - line_angle = GetAngleAtPoint(t,pos,&ep1,&ep2); - pos = p; - found = TRUE; - } - } - } - if (!found) SnapPos( &pos ); + (context->Op == OP_BENCH) || (context->Op == OP_TBLEDGE) || + (context->Op == OP_BOX) || (context->Op == OP_FILLBOX) || + (context->Op == OP_POLY) || (context->Op == OP_POLYLINE) || (context->Op == OP_FILLPOLY) ) { + if (locked) pos = movePos; } if ((context->Op == OP_CURVE1 || context->Op == OP_CURVE2 || context->Op == OP_CURVE3 || context->Op == OP_CURVE4) && context->State == 1) { ; @@ -390,7 +409,7 @@ STATUS_T DrawGeomMouse( tempSegs(0).u.l.option = 0; } tempSegs_da.cnt = 0; - context->message( _("Drag to next point, +Shift to lock to object, +Ctrl to lock to 90deg") ); + context->message( _("Drag next point, +Alt reverse Magnetic Snap or +Ctrl lock to 90 deg") ); break; case OP_TBLEDGE: OnTableEdgeEndPt( NULL, &pos ); @@ -399,8 +418,9 @@ STATUS_T DrawGeomMouse( tempSegs(0).color = context->Color; tempSegs(0).width = (mainD.scale<=16)?(3/context->D->dpi*context->D->scale):0; tempSegs(0).u.l.pos[0] = tempSegs(0).u.l.pos[1] = pos; + tempSegs(0).u.l.option = 0; tempSegs_da.cnt = 0; - context->message( _("Drag to place next end point") ); + context->message( _("Drag next point, +Alt reverse Magnetic Snap, or +Ctrl to lock to 90 degrees") ); break; case OP_CURVE1: case OP_CURVE2: case OP_CURVE3: case OP_CURVE4: if (context->State == 0) { @@ -432,6 +452,7 @@ STATUS_T DrawGeomMouse( tempSegs(0).u.c.radius = 0; tempSegs(0).u.c.center = pos; context->message( _("Drag to set radius") ); + context->State = 1; break; case OP_FILLBOX: width = 0; @@ -485,36 +506,59 @@ STATUS_T DrawGeomMouse( segPtr->u.l.pos[1] = pos; context->State = 1; segCnt = tempSegs_da.cnt; - context->message(_("+Shift - lock to close object, +Ctrl - lock to 90 deg")); + context->message(_("+Alt - reverse Magnetic Snap or +Ctrl - lock to 90 deg")); break; } return C_CONTINUE; + case wActionRDrag: case wActionLDrag: DYNARR_RESET(trkSeg_t, anchors_da ); + coOrd p = pos1 = pos; + BOOL_T locked = FALSE, poslocked = FALSE; if ((context->Op == OP_CURVE1 && context->State == 1) || (context->Op == OP_CURVE2 && context->State == 0) || - (context->Op == OP_CURVE4 && context->State != 2) || - (context->Op == OP_LINE) || - (context->Op == OP_BENCH) ) { - if (( (MyGetKeyState() & WKEY_ALT)==0) == magneticSnap) { - if (OnTrack( &pos, FALSE, FALSE )!=NULL) - CreateEndAnchor(pos,TRUE); - } - } else if (context->Op == OP_DIMLINE) { - if (OnTrack( &pos, FALSE, FALSE )!=NULL) CreateEndAnchor(pos,TRUE); - } + (context->Op == OP_CURVE4 && context->State != 1) || + (context->Op == OP_CIRCLE2 && context->State != 0) || + (context->Op == OP_CIRCLE3 && context->State == 0) || + (context->Op == OP_FILLCIRCLE2 && context->State != 0) || + (context->Op == OP_FILLCIRCLE3 && context->State == 0) || + (context->Op == OP_BOX ) || + (context->Op == OP_FILLBOX ) || + (context->Op == OP_DIMLINE ) || (context->Op == OP_TBLEDGE) || + (context->Op == OP_LINE ) || (context->Op == OP_BENCH) || + (context->Op == OP_POLY) || (context->Op == OP_POLYLINE) || (context->Op == OP_FILLPOLY) ) { + if ( ( (MyGetKeyState() & WKEY_ALT)==0) == magneticSnap) { + p = pos; + if ((OnTrack( &p, FALSE, FALSE )!=NULL) && (IsClose(FindDistance(p,pos)))) { + poslocked = TRUE; + pos1 = p; - pos1 = pos; + } + } + if (!poslocked) { //Set up poslock and pos1 for later + p = pos; + if (SnapPos(&p)) { + poslocked = TRUE; + pos1 = p; + } + } + } switch (context->Op) { case OP_TBLEDGE: - OnTableEdgeEndPt( NULL, &pos1 ); + if ((MyGetKeyState() & WKEY_CTRL) == WKEY_CTRL) { //If +Ctrl, snap to table edge end + p = pos; + if (OnTableEdgeEndPt( NULL, &p )) { + locked = TRUE; + pos1 = p; + } + } /* no break */ case OP_LINE: case OP_DIMLINE: case OP_BENCH: - if ((MyGetKeyState() & (WKEY_SHIFT|WKEY_CTRL|WKEY_ALT)) == WKEY_CTRL ) { + if (!locked && ((MyGetKeyState() & WKEY_CTRL) == WKEY_CTRL )) { //If not found already +Ctl = Right Angle //Snap to Right-Angle from previous or from 0 DIST_T l = FindDistance(pos0, pos); ANGLE_T angle2 = NormalizeAngle(FindAngle(pos0, pos)-line_angle); @@ -537,12 +581,12 @@ STATUS_T DrawGeomMouse( FormatDistance(FindDistance( pos0, pos1 )), PutAngle(FindAngle( pos0, pos1 )) ); tempSegs_da.cnt = 1; - if (anchors_da.cnt == 0) CreateEndAnchor(pos, FALSE); + if (anchors_da.cnt == 0) CreateEndAnchor(pos1, FALSE); break; case OP_POLY: case OP_FILLPOLY: case OP_POLYLINE: - if ((MyGetKeyState() & (WKEY_SHIFT|WKEY_CTRL|WKEY_ALT)) == WKEY_CTRL ) { + if ((MyGetKeyState() & WKEY_CTRL) == WKEY_CTRL ) { coOrd last_point = zero; ANGLE_T last_angle, initial_angle; if (tempSegs_da.cnt == 1) { @@ -571,22 +615,23 @@ STATUS_T DrawGeomMouse( } CreateEndAnchor(pos,TRUE); if (FindDistance(pos,last_point)>0.0) CreateLineAnchor(pos,last_point); - } - //If there is any point on this line that will give a 90 degree return to the first point, show it - if (tempSegs_da.cnt > 1) { - coOrd intersect; - ANGLE_T an_this = FindAngle(tempSegs(tempSegs_da.cnt-2).u.l.pos[1],pos); - if (FindIntersection(&intersect,tempSegs(0).u.l.pos[0],an_this+90.0,tempSegs(tempSegs_da.cnt-2).u.l.pos[1],an_this)) { - ANGLE_T an_inter = FindAngle(tempSegs(tempSegs_da.cnt-2).u.l.pos[1],intersect); - if (fabs(DifferenceBetweenAngles(an_inter,an_this))<90.0) { - CreateSquareAnchor(intersect); - d = FindDistance(intersect,pos); - if (IsClose(d)) { - pos = intersect; + //If there is any point on this line that will give a 90 degree return to the first point, show it + if (tempSegs_da.cnt > 1) { + coOrd intersect; + ANGLE_T an_this = FindAngle(tempSegs(tempSegs_da.cnt-2).u.l.pos[1],pos); + if (FindIntersection(&intersect,tempSegs(0).u.l.pos[0],an_this+90.0,tempSegs(tempSegs_da.cnt-2).u.l.pos[1],an_this)) { + ANGLE_T an_inter = FindAngle(tempSegs(tempSegs_da.cnt-2).u.l.pos[1],intersect); + if (fabs(DifferenceBetweenAngles(an_inter,an_this))<90.0) { + CreateSquareAnchor(intersect); + d = FindDistance(intersect,pos); + if (IsClose(d)) { + pos = intersect; + } } } } - } + } else if (poslocked) pos = pos1; + tempSegs(tempSegs_da.cnt-1).type = SEG_STRLIN; tempSegs(tempSegs_da.cnt-1).u.l.pos[1] = pos; context->message( _("Length = %s, Angle = %0.2f"), @@ -596,10 +641,10 @@ STATUS_T DrawGeomMouse( break; case OP_CURVE1: case OP_CURVE2: case OP_CURVE3: case OP_CURVE4: if (context->State == 0) { - pos0x = pos; + pos0x = pos1; CreateCurve( C_MOVE, pos, FALSE, context->Color, width, drawGeomCurveMode, &anchors_da, context->message ); } else { - PlotCurve( drawGeomCurveMode, pos0, pos0x, pos1, &context->ArcData, FALSE ); + PlotCurve( drawGeomCurveMode, pos0, pos0x, pos1, &context->ArcData, FALSE, 0.0 ); tempSegs(0).color = context->Color; tempSegs(0).width = width; DYNARR_SET(trkSeg_t,tempSegs_da,1); @@ -636,7 +681,7 @@ STATUS_T DrawGeomMouse( FormatDistance(context->ArcData.curveRadius), context->ArcData.a1, FormatDistance(context->ArcData.curveRadius*d) ); if (context->Op == OP_CURVE1 || context->Op == OP_CURVE4 ) - DrawArrowHeadsArray(&anchors_da,pos,FindAngle(context->ArcData.curvePos,pos),TRUE,wDrawColorRed); + DrawArrowHeadsArray(&anchors_da,pos1,FindAngle(context->ArcData.curvePos,pos),TRUE,wDrawColorRed); else if (context->Op == OP_CURVE2 || context->Op == OP_CURVE3 ) { CreateEndAnchor(context->ArcData.pos2,FALSE); DrawArrowHeadsArray(&anchors_da,context->ArcData.pos2,FindAngle(context->ArcData.curvePos,context->ArcData.pos2)+90,TRUE,wDrawColorRed); @@ -652,9 +697,16 @@ STATUS_T DrawGeomMouse( case OP_CIRCLE2: case OP_FILLCIRCLE2: tempSegs(0).u.c.center = pos1; - /* no break */ + if (context->State == 1 && locked) CreateEndAnchor(pos1, FALSE); + else wSetCursor(mainD.d,defaultCursor); + tempSegs(0).u.c.radius = FindDistance( pos0, pos1 ); + context->message( _("Radius = %s"), + FormatDistance(FindDistance( pos0, pos1 )) ); + break; case OP_CIRCLE3: case OP_FILLCIRCLE3: + if (context->State == 1) CreateEndAnchor(pos0, TRUE); + wSetCursor(mainD.d,defaultCursor); tempSegs(0).u.c.radius = FindDistance( pos0, pos1 ); context->message( _("Radius = %s"), FormatDistance(FindDistance( pos0, pos1 )) ); @@ -663,55 +715,51 @@ STATUS_T DrawGeomMouse( case OP_FILLBOX: tempSegs_da.cnt = 4; tempSegs(0).u.l.pos[1].x = tempSegs(1).u.l.pos[0].x = - tempSegs(1).u.l.pos[1].x = tempSegs(2).u.l.pos[0].x = pos.x; + tempSegs(1).u.l.pos[1].x = tempSegs(2).u.l.pos[0].x = pos1.x; tempSegs(1).u.l.pos[1].y = tempSegs(2).u.l.pos[0].y = - tempSegs(2).u.l.pos[1].y = tempSegs(3).u.l.pos[0].y = pos.y; + tempSegs(2).u.l.pos[1].y = tempSegs(3).u.l.pos[0].y = pos1.y; + if (locked) CreateEndAnchor(pos1,FALSE); context->message( _("Width = %s, Height = %s"), FormatDistance(fabs(pos1.x - pos0.x)), FormatDistance(fabs(pos1.y - pos0.y)) ); break; } + wSetCursor(mainD.d,wCursorNone); return C_CONTINUE; case wActionLUp: + case wActionRUp: lastValid = FALSE; createTrack = FALSE; - if ((context->Op == OP_CURVE1 && context->State == 1) || - (context->Op == OP_CURVE2 && context->State == 0) || - (context->Op == OP_CURVE3 && context->State != 0) || - (context->Op == OP_CURVE4 && context->State != 2) || - (context->Op == OP_LINE) || (context->Op == OP_DIMLINE) || - (context->Op == OP_BENCH) ) { - if (((MyGetKeyState() & WKEY_ALT)==0) == magneticSnap ) { - coOrd p = pos1; - track_p t; - if ((t=OnTrack(&p,FALSE,FALSE))) { - pos1 = p; - if (context->Op == OP_LINE || context->Op == OP_DIMLINE || context->Op == OP_BENCH) { - tempSegs(0).u.l.pos[1] = p; - } else { - PlotCurve( drawGeomCurveMode, pos0, pos0x, pos1, &context->ArcData, FALSE ); - if (context->ArcData.type == curveTypeStraight) { - DYNARR_RESET(trkSeg_t,tempSegs_da); - DYNARR_APPEND(trkSeg_t,tempSegs_da,1); - tempSegs(0).type = SEG_STRLIN; - tempSegs(0).u.l.pos[0] = pos0; - tempSegs(0).u.l.pos[1] = context->ArcData.pos1; - tempSegs_da.cnt = 1; - } else if (context->ArcData.type == curveTypeNone) { - DYNARR_RESET(trkSeg_t,tempSegs_da); - } else if (context->ArcData.type == curveTypeCurve) { - DYNARR_RESET(trkSeg_t,tempSegs_da); - DYNARR_APPEND(trkSeg_t,tempSegs_da,1); - tempSegs(0).type = SEG_CRVLIN; - tempSegs(0).u.c.center = context->ArcData.curvePos; - tempSegs(0).u.c.radius = context->ArcData.curveRadius; - tempSegs(0).u.c.a0 = context->ArcData.a0; - tempSegs(0).u.c.a1 = context->ArcData.a1; - tempSegs_da.cnt = 1; - } - } - - } + //Note - pos1 is last drag point + wSetCursor(mainD.d,defaultCursor); + if ((context->Op == OP_POLY) || (context->Op == OP_POLYLINE) || (context->Op == OP_FILLPOLY ) + || (context->Op == OP_BOX) || (context->Op == OP_FILLBOX) ){ ; + } else if (context->Op == OP_LINE || context->Op == OP_DIMLINE || + context->Op == OP_BENCH || context->Op == OP_TBLEDGE ) { + tempSegs(0).u.l.pos[1] = pos1; + } else if ((context->Op>=OP_FILLCIRCLE1 && context->Op<=OP_FILLCIRCLE3) || + (context->Op>=OP_CIRCLE1 && context->Op<=OP_CIRCLE3)) { + ; + } else { + PlotCurve( drawGeomCurveMode, pos0, pos0x, pos1, &context->ArcData, FALSE, 0.0 ); + if (context->ArcData.type == curveTypeStraight) { + DYNARR_RESET(trkSeg_t,tempSegs_da); + DYNARR_APPEND(trkSeg_t,tempSegs_da,1); + tempSegs(0).type = SEG_STRLIN; + tempSegs(0).u.l.pos[0] = pos0; + tempSegs(0).u.l.pos[1] = context->ArcData.pos1; + tempSegs_da.cnt = 1; + } else if (context->ArcData.type == curveTypeNone) { + DYNARR_RESET(trkSeg_t,tempSegs_da); + } else if (context->ArcData.type == curveTypeCurve) { + DYNARR_RESET(trkSeg_t,tempSegs_da); + DYNARR_APPEND(trkSeg_t,tempSegs_da,1); + tempSegs(0).type = SEG_CRVLIN; + tempSegs(0).u.c.center = context->ArcData.curvePos; + tempSegs(0).u.c.radius = context->ArcData.curveRadius; + tempSegs(0).u.c.a0 = context->ArcData.a0; + tempSegs(0).u.c.a1 = context->ArcData.a1; + tempSegs_da.cnt = 1; } } switch ( context->Op ) { @@ -733,6 +781,7 @@ STATUS_T DrawGeomMouse( pos0x = pos1; CreateCurve( C_UP, pos, FALSE, context->Color, width, drawGeomCurveMode, &anchors_da, context->message ); context->message( _("Drag on Red arrows to adjust curve") ); + context->show = FALSE; return C_CONTINUE; } else { DYNARR_SET(trkSeg_t,tempSegs_da,1); @@ -761,8 +810,15 @@ STATUS_T DrawGeomMouse( lastValid = TRUE; lastPos = pos1; context->State = 2; + if (context->Op == OP_CURVE1 || context->Op == OP_CURVE4 ) + DrawArrowHeadsArray(&anchors_da,pos1,FindAngle(context->ArcData.curvePos,pos),TRUE,wDrawColorRed); + else if (context->Op == OP_CURVE2 || context->Op == OP_CURVE3 ) { + CreateEndAnchor(context->ArcData.pos2,FALSE); + DrawArrowHeadsArray(&anchors_da,context->ArcData.pos2,FindAngle(context->ArcData.curvePos,context->ArcData.pos2)+90,TRUE,wDrawColorRed); + } + CreateEndAnchor(context->ArcData.curvePos,TRUE); /*drawContext = context; - DrawGeomOp( (void*)context->Op );*/ + DrawGeomOp( I2VP(context->Op) );*/ } break; case OP_CIRCLE1: @@ -792,7 +848,7 @@ STATUS_T DrawGeomMouse( tempSegs(0).u.p.polyType = RECTANGLE; tempSegs_da.cnt = 1; /*drawContext = context; - DrawGeomOp( (void*)context->Op );*/ + DrawGeomOp( I2VP(context->Op) );*/ context->length = FindDistance(pts[0].pt,pts[1].pt); context->width = FindDistance(pts[3].pt,pts[0].pt); context->State = 2; @@ -842,13 +898,14 @@ STATUS_T DrawGeomMouse( return C_CONTINUE; } context->Started = FALSE; - context->Changed = TRUE; //Update screen shown /*CheckOk();*/ if (context->State == 2 && IsCurCommandSticky()) { segCnt = tempSegs_da.cnt; + UndoStart("Create Lines","Sticky Draw"); + context->UndoStarted = TRUE; return C_CONTINUE; } - DrawGeomOk(); + DrawGeomOk(FALSE); context->State = 0; context->Changed = FALSE; context->message(""); @@ -856,8 +913,10 @@ STATUS_T DrawGeomMouse( case wActionText: DYNARR_RESET(trkSeg_t, anchors_da ); - if ( ((action>>8)&0xFF) == 0x0D || - ((action>>8)&0xFF) == ' ' ) { + int key = (action>>8&0xFF); + if ( key == 0x0D || + key == ' ' || + (key == 0x09 && ((MyGetKeyState() & (WKEY_SHIFT|WKEY_CTRL|WKEY_ALT)) != WKEY_SHIFT))) { //Tab continue if ((context->Op == OP_POLY) || (context->Op == OP_FILLPOLY) || (context->Op == OP_POLYLINE)) { tempSegs_da.cnt = segCnt; //If last segment wasn't just a point, add another starting on its end @@ -872,22 +931,32 @@ STATUS_T DrawGeomMouse( DYNARR_RESET(pts_t, points_da); DYNARR_RESET(trkSeg_t,tempSegs_da); } else { - if (context->State == 2) + if (context->State == 2) { tempSegs_da.cnt = segCnt; - DrawGeomOk(); + DrawGeomOk(context->UndoStarted); + context->UndoStarted = FALSE; + + } } + context->State = 0; + segCnt = 0; + if (key == 0x0D) return C_CONTINUE; //Esc - go to Reset + else return C_TERMINATE; //Space/Enter/Tab - end command + } else if (key == 0x09 && ((MyGetKeyState() & (WKEY_SHIFT|WKEY_CTRL|WKEY_ALT)) == WKEY_SHIFT)) { //Tab plus shift - abandon + context->State = 0; + segCnt = 0; + return C_TERMINATE; } - context->State = 0; - segCnt = 0; - return C_TERMINATE; + return C_CONTINUE; - case C_CANCEL: - if (context->Changed) { //If the update values were shown - if (context->State == 2) { - tempSegs_da.cnt = segCnt; - DrawGeomOk(); - } + case C_CONFIRM: + if (context->State==2 && IsCurCommandSticky()) { + DrawGeomOk(context->UndoStarted); } + context->Changed = FALSE; + return C_CONTINUE; + + case C_CANCEL: DYNARR_RESET(trkSeg_t, anchors_da ); tempSegs_da.cnt = 0; context->message( "" ); @@ -949,12 +1018,14 @@ void static CreateLineAnchors(int index, coOrd p0, coOrd p1) { anchors(1).color = wDrawColorBlue; anchors(1).u.c.radius = d/2; anchors(1).u.c.center = p1; + if (index>=0) wSetCursor(mainD.d,wCursorNone); } void static CreateBoxAnchors(int index, pts_t pt[4]) { DYNARR_RESET(trkSeg_t,anchors_da); double d = tempD.scale*0.15; ANGLE_T a = FindAngle(pt[0].pt,pt[1].pt); ANGLE_T diag = FindAngle(pt[0].pt,pt[2].pt); + if (index>=0) wSetCursor(mainD.d,wCursorNone); for (int i=0;i<4;i++) { DYNARR_SET(trkSeg_t,anchors_da,anchors_da.cnt+5); DrawArrowHeads(&DYNARR_N(trkSeg_t,anchors_da,anchors_da.cnt-5),pt[i].pt,(diag>a?45.0:-45.0)+a+(90.0*(i)),TRUE,i==index?wDrawColorRed:wDrawColorBlue); @@ -979,7 +1050,7 @@ void static CreateOriginAnchor(coOrd origin, wBool_t trans_selected) { anchors(i).type = SEG_STRLIN; anchors(i).u.l.pos[0] = p0; anchors(i).u.l.pos[1] = p1; - anchors(i).color = wDrawColorBlue; + anchors(i).color = trans_selected?wDrawColorAqua:wDrawColorBlue; anchors(i).width = 0; DYNARR_APPEND(trkSeg_t,anchors_da,1); Translate(&p0,origin,90,d*4); @@ -990,6 +1061,7 @@ void static CreateOriginAnchor(coOrd origin, wBool_t trans_selected) { anchors(i).u.l.pos[1] = p1; anchors(i).color = wDrawColorBlue; anchors(i).width = 0; + if (trans_selected) wSetCursor(mainD.d,wCursorNone); } void static CreateCurveAnchors(int index, coOrd pm, coOrd pc, coOrd p0, coOrd p1) { @@ -1011,6 +1083,8 @@ void static CreateCurveAnchors(int index, coOrd pm, coOrd pc, coOrd p0, coOrd p1 anchors(1).width = 0; DYNARR_SET(trkSeg_t,anchors_da,anchors_da.cnt+5); DrawArrowHeads(&DYNARR_N(trkSeg_t,anchors_da,anchors_da.cnt-5),pm,FindAngle(pm,pc),TRUE,index==2?wDrawColorAqua:wDrawColorBlue); + if (index>=0) wSetCursor(mainD.d,wCursorNone); + else wSetCursor(mainD.d,defaultCursor); } void static CreatePolyAnchors(int index) { @@ -1065,6 +1139,7 @@ void CreateMovingAnchor(coOrd pos,BOOL_T fill) { anchors(inx).color = wDrawColorBlue; anchors(inx).u.c.radius = d/4; anchors(inx).u.c.center = pos; + wSetCursor(mainD.d,wCursorNone); } /* @@ -1142,9 +1217,10 @@ STATUS_T DrawGeomPolyModify( return C_CONTINUE; } } + wSetCursor(mainD.d,defaultCursor); int pInx=0; coOrd pm0,pm1; - DIST_T dm = 10000.0; + DIST_T dm = DIST_INF; for ( int inx=0; inx<points_da.cnt; inx++ ) { pm0 = pos; DIST_T ddm = LineDistance( &pm0, points( inx==0?points_da.cnt-1:inx-1).pt, points(inx).pt ); @@ -1169,7 +1245,7 @@ STATUS_T DrawGeomPolyModify( return C_CONTINUE; break; case C_DOWN: - d = 10000.0; + d = DIST_INF; polyInx = -1; coOrd p0; double dd; @@ -1329,7 +1405,7 @@ STATUS_T DrawGeomPolyModify( next_inx = first_inx+1; } //Lock to 90 degrees first/last point - if ((MyGetKeyState() & (WKEY_SHIFT|WKEY_CTRL|WKEY_ALT)) == WKEY_SHIFT ) { + if ((MyGetKeyState() & (WKEY_SHIFT|WKEY_CTRL|WKEY_ALT)) == WKEY_CTRL ) { ANGLE_T last_angle,next_angle; coOrd last_point,next_point; if (first_inx == 0) { @@ -1388,7 +1464,7 @@ STATUS_T DrawGeomPolyModify( FormatDistance(FindDistance(pos_lock,last_point)), PutAngle(FindAngle(pos_lock,last_point))); - } + } else SnapPos(&pos); //If not using CTL and snap enabled } context->prev_inx = first_inx; coOrd diff; @@ -1463,24 +1539,24 @@ STATUS_T DrawGeomPolyModify( break; case C_TEXT: if (action>>8 == 'o') { //"o" -> origin mode - MenuMode(1); + MenuMode(I2VP(1)); InfoMessage("Move Origin Mode: Place Origin, p for Points, Enter or Esc"); return C_CONTINUE; } - if (((prev_inx>=0 && tempSegs(0).u.p.polyType != POLYLINE) || (prev_inx>=1 && prev_inx<=points_da.cnt-2)) && + if (((prev_inx>=0 && tempSegs(0).u.p.polyType != POLYLINE) || + ((tempSegs(0).u.p.polyType == POLYLINE) && (prev_inx>=1) && (prev_inx<=points_da.cnt-2)) ) && ((action>>8 == 's') || (action>>8 == 'v') || (action>>8 == 'r'))) { switch(action>>8) { case 's': points(context->prev_inx).pt_type = wPolyLineSmooth; - break; + return C_CONTINUE; case 'v': points(context->prev_inx).pt_type = wPolyLineStraight; - break; + return C_CONTINUE; case 'r': points(context->prev_inx).pt_type = wPolyLineRound; - break; - default: return C_CONTINUE; + default:; } } if ((action>>8 == 'g') && (tempSegs(0).type == SEG_POLY) && (tempSegs(0).u.p.polyType == POLYLINE) ) { @@ -1499,14 +1575,18 @@ STATUS_T DrawGeomPolyModify( } if ((action>>8 == 'f') && (tempSegs(0).type == SEG_POLY) && (tempSegs(0).u.p.polyType != POLYLINE )) { tempSegs(0).type = SEG_FILPOLY; + tempSegs(0).u.p.polyType = FREEFORM; context->type = SEG_FILPOLY; + context->subtype=FREEFORM; context->filled = TRUE; CreatePolyAnchors( -1); return C_CONTINUE; } if ((action>>8 == 'u') && (tempSegs(0).type == SEG_FILPOLY) ) { tempSegs(0).type = SEG_POLY; + tempSegs(0).u.p.polyType = FREEFORM; context->type = SEG_POLY; + context->subtype=FREEFORM; context->filled = FALSE; CreatePolyAnchors( -1); return C_CONTINUE; @@ -1532,6 +1612,8 @@ STATUS_T DrawGeomPolyModify( selected_count=0; tempSegs(0).u.p.cnt = points_da.cnt; context->max_inx = points_da.cnt-1; + } else { + ErrorMessage( MSG_POLY_NOTHING_SELECTED ); } prev_inx = -1; context->prev_inx = -1; @@ -1541,15 +1623,35 @@ STATUS_T DrawGeomPolyModify( InfoMessage(_("Point Deleted")); return C_CONTINUE; } - if (action>>8 != 32 && action>>8 != 13) return C_CONTINUE; + if (action>>8 != 32 && action>>8 != 13 && action>>8 !=9) return C_CONTINUE; + if (action>>8 == 9 && (MyGetKeyState() & WKEY_SHIFT) != 0) return C_TERMINATE; /* no break */ + case C_CONFIRM: + case C_OK: case C_FINISH: //copy changes back into track - if (polyState != POLY_SELECTED) return C_TERMINATE; + if (polyState != POLY_SELECTED) { + polyState = POLY_NONE; + DYNARR_RESET(trkSeg_t,anchors_da); + DYNARR_RESET(trkSeg_t,tempSegs_da); + return C_TERMINATE; + } + //If ends overlap precisely remove last segment and close if >3 points + DIST_T dist = FindDistance(points(0).pt,points(points_da.cnt-1).pt); + if (IsClose(dist*4) && points_da.cnt>3 && tempSegs(0).u.p.polyType == POLYLINE) { + tempSegs(0).u.p.polyType = FREEFORM; + context->subtype=FREEFORM; + context->open = FALSE; + points_da.cnt--; + select_da.cnt--; + selected_count=0; + tempSegs(0).u.p.cnt = points_da.cnt; + context->max_inx = points_da.cnt-1; + } pts_t * oldPts = context->segPtr[segInx].u.p.pts; void * newPts = (pts_t*)MyMalloc( points_da.cnt * sizeof (pts_t) ); context->segPtr[segInx].u.p.pts = newPts; - context->segPtr->u.p.cnt = points_da.cnt; + context->segPtr[segInx].u.p.cnt = points_da.cnt; context->orig = rotate_origin; context->angle = rotate_angle; for (int i=0; i<points_da.cnt; i++) { @@ -1561,12 +1663,12 @@ STATUS_T DrawGeomPolyModify( context->segPtr[segInx].u.p.pts[i].pt_type = points(i).pt_type; } MyFree(oldPts); - oldPts = NULL; polyState = POLY_NONE; DYNARR_RESET(trkSeg_t,anchors_da); + DYNARR_RESET(trkSeg_t,points_da); DYNARR_RESET(trkSeg_t,tempSegs_da); - DrawNewTrack( context->trk ); - return C_TERMINATE; + if ((action&0xFF)==C_CONFIRM) return C_CONTINUE; + else return C_TERMINATE; case C_REDRAW: if (polyState == POLY_NONE) return C_CONTINUE; DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt,trackGauge, wDrawColorBlack); @@ -1644,7 +1746,7 @@ STATUS_T DrawGeomOriginMove( return C_CONTINUE; break; case wActionMove: - CreateOriginAnchor(context->rot_center, TRUE); + CreateOriginAnchor(context->rot_center, FALSE); if ((tempSegs(0).type == SEG_POLY || tempSegs(0).type == SEG_FILPOLY) && (context->prev_inx>=0)) { CreateSelectedAnchor(points(context->prev_inx).pt); } @@ -1724,7 +1826,7 @@ STATUS_T DrawGeomOriginMove( } } if (action>>8 == 'p') { //"p" - points mode - MenuMode(0); + MenuMode(I2VP(0)); return C_CONTINUE; } context->rel_center = context->rot_center; @@ -1803,6 +1905,7 @@ STATUS_T DrawGeomModify( tempSegs(0).u.l.pos[1] = p1; tempSegs(0).width = 0; tempSegs_da.cnt = 1; + tempSegs(0).u.l.option = context->segPtr[segInx].u.l.option; context->p0 = p0; context->p1 = p1; CreateLineAnchors(-1,p0,p1); @@ -1861,6 +1964,7 @@ STATUS_T DrawGeomModify( if (context->rotate_state) return DrawGeomOriginMove(action,pos,context); if (polyMode) return DrawGeomPolyModify(action,pos,context); DYNARR_RESET(trkSeg_t,anchors_da); + wSetCursor(mainD.d,defaultCursor); switch( context->type) { case SEG_TBLEDGE: case SEG_STRLIN: @@ -1881,19 +1985,28 @@ STATUS_T DrawGeomModify( case SEG_CRVLIN: case SEG_FILCRCL: DYNARR_RESET(trkSeg_t,anchors_da); - if (tempSegs(0).u.c.a1 < 360.0) - CreateCurveAnchors(curveInx,context->pm,context->pc,context->p0,context->p1); - dd = FindDistance( context->p0, pos ); - if ( IsClose(dd)) { - CreateMovingAnchor(context->p0,TRUE); + if (tempSegs(0).u.c.a1 >= 360.0) { + if (IsClose(FindDistance(context->pc,pos)-context->radius)) { + coOrd p; + Translate(&p,context->pc,FindAngle(context->pc,pos),context->radius); + CreateMovingAnchor(p,TRUE); + DYNARR_SET(trkSeg_t,anchors_da,anchors_da.cnt+5); + DrawArrowHeads(&DYNARR_N(trkSeg_t,anchors_da,anchors_da.cnt-5),p,FindAngle(context->pc,pos),TRUE,wDrawColorBlue); + } } else { - dd = FindDistance( context->p1, pos ); + CreateCurveAnchors(curveInx,context->pm,context->pc,context->p0,context->p1); + dd = FindDistance( context->p0, pos ); if ( IsClose(dd)) { - CreateMovingAnchor(context->p1,TRUE); + CreateMovingAnchor(context->p0,TRUE); } else { - dd = FindDistance( context->pm, pos ); + dd = FindDistance( context->p1, pos ); if ( IsClose(dd)) { - CreateMovingAnchor(context->pm,TRUE); + CreateMovingAnchor(context->p1,TRUE); + } else { + dd = FindDistance( context->pm, pos ); + if ( IsClose(dd)) { + CreateMovingAnchor(context->pm,TRUE); + } } } } @@ -1916,8 +2029,6 @@ STATUS_T DrawGeomModify( tempSegs(0).color = context->segPtr[segInx].color; switch ( context->type ) { case SEG_TBLEDGE: - if ( MyGetKeyState() & WKEY_CTRL ) - OnTableEdgeEndPt( NULL, &pos ); case SEG_STRLIN: case SEG_DIMLIN: case SEG_BENCH: @@ -1936,7 +2047,10 @@ STATUS_T DrawGeomModify( if (lineInx < 0 ) { InfoMessage( _("Not close to end of line")); } else { - InfoMessage("End selected, drag to reposition"); + if (context->type == SEG_TBLEDGE) + InfoMessage("End selected, drag to move +Ctl to lock to other edge end, +Shift lock to line"); + else + InfoMessage("End selected, drag to reposition +Shift lock to line"); context->state = MOD_SELECTED_PT; } tempSegs(0).color = wDrawColorBlack; @@ -2005,6 +2119,7 @@ STATUS_T DrawGeomModify( case SEG_FILPOLY: d = 10000; polyInx = 0; + wSetCursor(mainD.d,wCursorNone); for ( inx=0; inx<4; inx++ ) { if (IsClose(FindDistance(pos,points(inx).pt))) { corner_mode = TRUE; @@ -2071,21 +2186,36 @@ STATUS_T DrawGeomModify( UndrawNewTrack( context->trk ); return C_CONTINUE; case C_MOVE: - if (context->rotate_state) return DrawGeomOriginMove(action,pos,context); + if (context->rotate_state) return DrawGeomOriginMove(action,pos,context); if (polyMode) return DrawGeomPolyModify(action,pos,context); if (context->state != MOD_SELECTED_PT) return C_CONTINUE; + BOOL_T locked = FALSE; switch (tempSegs(0).type) { + case SEG_TBLEDGE: + if ( (MyGetKeyState() & WKEY_CTRL) == WKEY_CTRL ) { //Special Snap to Table End Point if Ctrl + if (OnTableEdgeEndPt( NULL, &pos )) { + locked = TRUE; + } + } + /* No Break*/ case SEG_STRLIN: case SEG_DIMLIN: case SEG_BENCH: - case SEG_TBLEDGE: - if ( (MyGetKeyState() & WKEY_SHIFT) != 0) { - d = FindDistance( pos, tempSegs(0).u.l.pos[1-lineInx] ); - Translate( &pos, tempSegs(0).u.l.pos[1-lineInx], segA1, d ); - } else if ((MyGetKeyState() & (WKEY_SHIFT|WKEY_CTRL|WKEY_ALT)) == WKEY_SHIFT ) { - OnTrack( &pos, FALSE, FALSE ); - CreateEndAnchor(pos,TRUE); + if (!locked) { + if ((MyGetKeyState() & WKEY_SHIFT) != 0) { //Shift is on same line + d = FindDistance( pos, tempSegs(0).u.l.pos[1-lineInx] ); + Translate( &pos, tempSegs(0).u.l.pos[1-lineInx], segA1, d ); + locked = TRUE; + } else if (((MyGetKeyState() & WKEY_ALT) == 0) == magneticSnap ) { //M.S. Either on or Off + if (OnTrack( &pos, FALSE, FALSE )!=NULL) { + CreateEndAnchor(pos,TRUE); + locked = TRUE; + } + } + }; + if (!locked) { + if (SnapPos(&pos)) locked = TRUE; } break; default: @@ -2096,9 +2226,6 @@ STATUS_T DrawGeomModify( tempSegs_da.cnt = 1; switch (tempSegs(0).type) { case SEG_TBLEDGE: - if ( MyGetKeyState() & WKEY_CTRL ) - OnTableEdgeEndPt( NULL, &pos ); - /* no break */ case SEG_STRLIN: case SEG_DIMLIN: case SEG_BENCH: @@ -2120,6 +2247,7 @@ STATUS_T DrawGeomModify( } else { if (context->state != MOD_SELECTED_PT) return C_CONTINUE; if (curveInx < 0 || curveInx > 2) return C_CONTINUE; + wSetCursor(mainD.d,wCursorNone); p0 = context->p0; p1 = context->p1; pc = context->pc; @@ -2227,6 +2355,7 @@ STATUS_T DrawGeomModify( break; case SEG_POLY: case SEG_FILPOLY: + wSetCursor(mainD.d,wCursorNone); if (!corner_mode) { /* Constrain movement to be perpendicular */ d = FindDistance(start_pos, pos); @@ -2267,9 +2396,7 @@ STATUS_T DrawGeomModify( } return C_CONTINUE; case C_UP: - if (context->rotate_state) return DrawGeomOriginMove(action, pos, context); - if (polyMode) { int rc; rc = DrawGeomPolyModify(action,pos,context); @@ -2277,7 +2404,7 @@ STATUS_T DrawGeomModify( context->state = MOD_AFTER_PT; return rc; } - + wSetCursor(mainD.d,defaultCursor); if (segInx == -1) return C_CONTINUE; switch (tempSegs(0).type) { @@ -2428,22 +2555,36 @@ STATUS_T DrawGeomModify( } } break; + case wActionExtKey: + if ((((action>>8)&0xFF)== wAccelKey_Del) && polyMode) //Convert Del key to be BackSpace in PolyModify + return DrawGeomPolyModify(C_TEXT+((int)(127<<8)),pos,context); + break; case C_TEXT: if (context->rotate_state) DrawGeomOriginMove(action, pos, context); if (polyMode) return DrawGeomPolyModify(action,pos,context); if (action>>8 == 'o') { - MenuMode(1); + MenuMode(I2VP(1)); } if (action>>8 != 32 && action>>8 != 13) return C_CONTINUE; /* no break */ + case C_CONFIRM: + return C_CONTINUE; + /* no break*/ + case C_OK: case C_FINISH: + UndoStart("Modify Draw", "OK"); + UndoModify(context->trk); if (polyMode) { DrawGeomPolyModify(action,pos,context); context->segPtr[segInx].type = context->type; context->segPtr[segInx].u.p.polyType = context->subtype; + if (context->segPtr[segInx].type == SEG_FILPOLY) + context->segPtr[segInx].u.p.polyType = FREEFORM; //Ensure Filled is closed + context->state = MOD_NONE; + DrawNewTrack( context->trk ); return C_TERMINATE; } //copy changes back into track @@ -2496,8 +2637,6 @@ STATUS_T DrawGeomModify( context->rotate_state = FALSE; context->last_inx = -1; DYNARR_RESET(trkSeg_t,anchors_da); - DYNARR_RESET(trkSeg_t,tempSegs_da); - DrawNewTrack( context->trk ); return C_TERMINATE; case C_REDRAW: if (polyMode) return DrawGeomPolyModify(action,pos,context); @@ -2506,13 +2645,12 @@ STATUS_T DrawGeomModify( DrawSegs( &tempD, zero, 0.0, &anchors(0), anchors_da.cnt, trackGauge, wDrawColorBlack ); break; case C_CANCEL: - case C_CONFIRM: - case C_TERMINATE: context->state = MOD_NONE; context->rotate_state = FALSE; context->rot_moved = FALSE; + polyMode = FALSE; DYNARR_RESET(trkSeg_t,anchors_da); - DYNARR_RESET(trkSeg_t,tempSegs_da); + DrawNewTrack( context->trk ); break; default: ; |