diff options
Diffstat (limited to 'app/bin/drawgeom.c')
-rw-r--r-- | app/bin/drawgeom.c | 721 |
1 files changed, 721 insertions, 0 deletions
diff --git a/app/bin/drawgeom.c b/app/bin/drawgeom.c new file mode 100644 index 0000000..8ef31e8 --- /dev/null +++ b/app/bin/drawgeom.c @@ -0,0 +1,721 @@ + +/* XTrkCad - Model Railroad CAD + * Copyright (C) 2005 Dave Bullis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <stdarg.h> +#include "track.h" +#include "ccurve.h" +#include "compound.h" +#include "drawgeom.h" +#include "i18n.h" + +/*EXPORT drawContext_t * drawContext;*/ +static long drawGeomCurveMode; + +#define contextSegs(N) DYNARR_N( trkSeg_t, context->Segs_da, N ) + + + +static dynArr_t points_da; +#define points(N) DYNARR_N( coOrd, points_da, N ) + +static void EndPoly( drawContext_t * context, int cnt ) +{ + trkSeg_p segPtr; + track_p trk; + long oldOptions; + coOrd * pts; + int inx; + + if (context->State==0 || cnt == 0) + return; + + oldOptions = context->D->funcs->options; + context->D->funcs->options |= wDrawOptTemp; + DrawSegs( context->D, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); + context->D->funcs->options = oldOptions; + + if (IsClose(FindDistance(tempSegs(0).u.l.pos[0], tempSegs(cnt-1).u.l.pos[1] ))) + cnt--; + if ( cnt < 2 ) { + tempSegs_da.cnt = 0; + ErrorMessage( MSG_POLY_SHAPES_3_SIDES ); + return; + } + pts = (coOrd*)MyMalloc( (cnt+1) * sizeof *(coOrd*)NULL ); + for ( inx=0; inx<cnt; inx++ ) + pts[inx] = tempSegs(inx).u.l.pos[0]; + pts[cnt] = tempSegs(cnt-1).u.l.pos[1]; + DYNARR_SET( trkSeg_t, tempSegs_da, 1 ); + segPtr = &tempSegs(0); + segPtr->type = ( context->Op == OP_POLY ? SEG_POLY: SEG_FILPOLY ); + segPtr->u.p.cnt = cnt+1; + segPtr->u.p.pts = pts; + segPtr->u.p.angle = 0.0; + segPtr->u.p.orig = zero; + UndoStart( _("Create Lines"), "newDraw" ); + trk = MakeDrawFromSeg( zero, 0.0, segPtr ); + DrawNewTrack( trk ); + tempSegs_da.cnt = 0; +} + + + +static void DrawGeomOk( void ) +{ + track_p trk; + int inx; + + if (tempSegs_da.cnt <= 0) + return; + UndoStart( _("Create Lines"), "newDraw" ); + for ( inx=0; inx<tempSegs_da.cnt; inx++ ) { + trk = MakeDrawFromSeg( zero, 0.0, &tempSegs(inx) ); + DrawNewTrack( trk ); + } + tempSegs_da.cnt = 0; +} + +/** + * Create and draw a graphics primitive (lines, arc, circle). The complete handling of mouse + * movements and clicks during the editing process is done here. + * + * \param action IN mouse action + * \param pos IN position of mouse pointer + * \param context IN/OUT parameters for drawing op + * \return next command state + */ + +STATUS_T DrawGeomMouse( + wAction_t action, + coOrd pos, + drawContext_t *context ) +{ + static int lastValid = FALSE; + static coOrd pos0, pos0x, pos1, lastPos; + trkSeg_p segPtr; + coOrd *pts; + int inx; + DIST_T width; + static int segCnt; + DIST_T d; + BOOL_T createTrack; + long oldOptions; + + width = context->Width/context->D->dpi; + + switch (action&0xFF) { + + case C_START: + context->State = 0; + context->Changed = FALSE; + segCnt = 0; + DYNARR_RESET( trkSeg_t, tempSegs_da ); + return C_CONTINUE; + + case wActionMove: + return C_CONTINUE; + + case wActionLDown: + context->Started = TRUE; + if ((context->Op == OP_CURVE1 || context->Op == OP_CURVE2 || context->Op == OP_CURVE3 || context->Op == OP_CURVE4) && context->State == 1) { + ; + } else { + if ( (MyGetKeyState() & (WKEY_SHIFT|WKEY_CTRL|WKEY_ALT)) == WKEY_CTRL ) + OnTrack( &pos, FALSE, FALSE ); + pos0 = pos; + pos1 = pos; + } + switch (context->Op) { + case OP_LINE: + case OP_DIMLINE: + case OP_BENCH: + if ( lastValid && ( MyGetKeyState() & WKEY_SHIFT ) ) { + pos = pos0 = lastPos; + } + DYNARR_SET( trkSeg_t, tempSegs_da, 1 ); + switch (context->Op) { + case OP_LINE: tempSegs(0).type = SEG_STRLIN; break; + case OP_DIMLINE: tempSegs(0).type = SEG_DIMLIN; break; + case OP_BENCH: tempSegs(0).type = SEG_BENCH; break; + } + tempSegs(0).color = context->Color; + tempSegs(0).width = width; + tempSegs(0).u.l.pos[0] = tempSegs(0).u.l.pos[1] = pos; + if ( context->Op == OP_BENCH || context->Op == OP_DIMLINE ) { + tempSegs(0).u.l.option = context->benchOption; + } else { + tempSegs(0).u.l.option = 0; + } + tempSegs_da.cnt = 0; + context->message( _("Drag to place next end point") ); + break; + case OP_TBLEDGE: + if ( lastValid && ( MyGetKeyState() & WKEY_SHIFT ) ) { + pos = pos0 = lastPos; + } + OnTableEdgeEndPt( NULL, &pos ); + DYNARR_SET( trkSeg_t, tempSegs_da, 1 ); + tempSegs(0).type = SEG_TBLEDGE; + 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_da.cnt = 0; + context->message( _("Drag to place next end point") ); + break; + case OP_CURVE1: case OP_CURVE2: case OP_CURVE3: case OP_CURVE4: + if (context->State == 0) { + switch ( context->Op ) { + case OP_CURVE1: drawGeomCurveMode = crvCmdFromEP1; break; + case OP_CURVE2: drawGeomCurveMode = crvCmdFromTangent; break; + case OP_CURVE3: drawGeomCurveMode = crvCmdFromCenter; break; + case OP_CURVE4: drawGeomCurveMode = crvCmdFromChord; break; + } + CreateCurve( C_DOWN, pos, FALSE, context->Color, width, drawGeomCurveMode, context->message ); + } else { + tempSegs_da.cnt = segCnt; + } + break; + case OP_CIRCLE1: + case OP_CIRCLE2: + case OP_CIRCLE3: + case OP_FILLCIRCLE1: + case OP_FILLCIRCLE2: + case OP_FILLCIRCLE3: + DYNARR_SET( trkSeg_t, tempSegs_da, 1 ); + tempSegs(0).type = SEG_CRVLIN; + tempSegs(0).color = context->Color; + if ( context->Op >= OP_CIRCLE1 && context->Op <= OP_CIRCLE3 ) + tempSegs(0).width = width; + else + tempSegs(0).width = 0; + tempSegs(0).u.c.a0 = 0; + tempSegs(0).u.c.a1 = 360; + tempSegs(0).u.c.radius = 0; + tempSegs(0).u.c.center = pos; + context->message( _("Drag to set radius") ); + break; + case OP_FILLBOX: + width = 0; + case OP_BOX: + DYNARR_SET( trkSeg_t, tempSegs_da, 4 ); + for ( inx=0; inx<4; inx++ ) { + tempSegs(inx).type = SEG_STRLIN; + tempSegs(inx).color = context->Color; + tempSegs(inx).width = width; + tempSegs(inx).u.l.pos[0] = tempSegs(inx).u.l.pos[1] = pos; + } + tempSegs_da.cnt = 0; + context->message( _("Drag set box size") ); + break; + case OP_POLY: + case OP_FILLPOLY: + tempSegs_da.cnt = segCnt; + DYNARR_APPEND( trkSeg_t, tempSegs_da, 10 ); + segPtr = &tempSegs(tempSegs_da.cnt-1); + segPtr->type = SEG_STRLIN; + segPtr->color = context->Color; + segPtr->width = (context->Op==OP_POLY?width:0); + if ( tempSegs_da.cnt == 1 ) { + segPtr->u.l.pos[0] = pos; + } else { + segPtr->u.l.pos[0] = segPtr[-1].u.l.pos[1]; + } + segPtr->u.l.pos[1] = pos; + context->State = 1; + oldOptions = context->D->funcs->options; + context->D->funcs->options |= wDrawOptTemp; + DrawSegs( context->D, zero, 0.0, &tempSegs(tempSegs_da.cnt-1), 1, trackGauge, wDrawColorBlack ); + context->D->funcs->options = oldOptions; + break; + } + return C_CONTINUE; + + case wActionLDrag: + oldOptions = context->D->funcs->options; + context->D->funcs->options |= wDrawOptTemp; + if (context->Op == OP_POLY || context->Op == OP_FILLPOLY) + DrawSegs( context->D, zero, 0.0, &tempSegs(tempSegs_da.cnt-1), 1, trackGauge, wDrawColorBlack ); + else + DrawSegs( context->D, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); + if ( (MyGetKeyState() & (WKEY_SHIFT|WKEY_CTRL|WKEY_ALT)) == WKEY_CTRL ) + OnTrack( &pos, FALSE, FALSE ); + pos1 = pos; + switch (context->Op) { + case OP_TBLEDGE: + OnTableEdgeEndPt( NULL, &pos1 ); + case OP_LINE: + case OP_DIMLINE: + case OP_BENCH: + tempSegs(0).u.l.pos[1] = pos1; + context->message( _("Length = %s, Angle = %0.2f"), + FormatDistance(FindDistance( pos0, pos1 )), + PutAngle(FindAngle( pos0, pos1 )) ); + tempSegs_da.cnt = 1; + break; + case OP_POLY: + case OP_FILLPOLY: + 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"), + FormatDistance(FindDistance( tempSegs(tempSegs_da.cnt-1).u.l.pos[0], pos )), + PutAngle(FindAngle( tempSegs(tempSegs_da.cnt-1).u.l.pos[0], pos )) ); + break; + case OP_CURVE1: case OP_CURVE2: case OP_CURVE3: case OP_CURVE4: + if (context->State == 0) { + pos0x = pos; + CreateCurve( C_MOVE, pos, TRUE, context->Color, width, drawGeomCurveMode, context->message ); + } else { + PlotCurve( drawGeomCurveMode, pos0, pos0x, pos1, &context->ArcData, FALSE ); + tempSegs(0).color = context->Color; + tempSegs(0).width = width; + if (context->ArcData.type == curveTypeStraight) { + 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; + context->message( _("Straight Line: Length=%s Angle=%0.3f"), + FormatDistance(FindDistance( pos0, context->ArcData.pos1 )), + PutAngle(FindAngle( pos0, context->ArcData.pos1 )) ); + } else if (context->ArcData.type == curveTypeNone) { + tempSegs_da.cnt = 0; + context->message( _("Back") ); + } else if (context->ArcData.type == curveTypeCurve) { + 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; + d = D2R(context->ArcData.a1); + if (d < 0.0) + d = 2*M_PI+d; + if ( d*context->ArcData.curveRadius > mapD.size.x+mapD.size.y ) { + ErrorMessage( MSG_CURVE_TOO_LARGE ); + tempSegs_da.cnt = 0; + context->ArcData.type = curveTypeNone; + context->D->funcs->options = oldOptions; + return C_CONTINUE; + } + context->message( _("Curved Line: Radius=%s Angle=%0.3f Length=%s"), + FormatDistance(context->ArcData.curveRadius), context->ArcData.a1, + FormatDistance(context->ArcData.curveRadius*d) ); + } + } + break; + case OP_CIRCLE1: + case OP_FILLCIRCLE1: + break; + case OP_CIRCLE2: + case OP_FILLCIRCLE2: + tempSegs(0).u.c.center = pos1; + case OP_CIRCLE3: + case OP_FILLCIRCLE3: + tempSegs(0).u.c.radius = FindDistance( pos0, pos1 ); + context->message( _("Radius = %s"), + FormatDistance(FindDistance( pos0, pos1 )) ); + break; + case OP_BOX: + 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].y = tempSegs(2).u.l.pos[0].y = + tempSegs(2).u.l.pos[1].y = tempSegs(3).u.l.pos[0].y = pos.y; + context->message( _("Width = %s, Height = %s"), + FormatDistance(fabs(pos1.x - pos0.x)), FormatDistance(fabs(pos1.y - pos0.y)) ); + break; + } + if (context->Op == OP_POLY || context->Op == OP_FILLPOLY) + DrawSegs( context->D, zero, 0.0, &tempSegs(tempSegs_da.cnt-1), 1, trackGauge, wDrawColorBlack ); + else + DrawSegs( context->D, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); + context->D->funcs->options = oldOptions; + return C_CONTINUE; + + case wActionLUp: + oldOptions = context->D->funcs->options; + context->D->funcs->options |= wDrawOptTemp; + if (context->Op != OP_POLY && context->Op != OP_FILLPOLY) + DrawSegs( context->D, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); + lastValid = FALSE; + createTrack = FALSE; + switch ( context->Op ) { + case OP_LINE: + case OP_DIMLINE: + case OP_BENCH: + case OP_TBLEDGE: + lastValid = TRUE; + lastPos = pos1; + break; + case OP_CURVE1: case OP_CURVE2: case OP_CURVE3: case OP_CURVE4: + if (context->State == 0) { + context->State = 1; + context->ArcAngle = FindAngle( pos0, pos1 ); + pos0x = pos1; + CreateCurve( C_UP, pos, TRUE, context->Color, width, drawGeomCurveMode, context->message ); + DrawSegs( context->D, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); + segCnt = tempSegs_da.cnt; + context->message( _("Drag on Red arrows to adjust curve") ); + context->D->funcs->options = oldOptions; + return C_CONTINUE; + } else { + tempSegs_da.cnt = 0; + if (context->ArcData.type == curveTypeCurve) { + tempSegs_da.cnt = 1; + segPtr = &tempSegs(0); + segPtr->type = SEG_CRVLIN; + segPtr->color = context->Color; + segPtr->width = width; + segPtr->u.c.center = context->ArcData.curvePos; + segPtr->u.c.radius = context->ArcData.curveRadius; + segPtr->u.c.a0 = context->ArcData.a0; + segPtr->u.c.a1 = context->ArcData.a1; + } else if (context->ArcData.type == curveTypeStraight) { + tempSegs_da.cnt = 1; + segPtr = &tempSegs(0); + segPtr->type = SEG_STRLIN; + segPtr->color = context->Color; + segPtr->width = width; + segPtr->u.l.pos[0] = pos0; + segPtr->u.l.pos[1] = pos1; + } else { + tempSegs_da.cnt = 0; + } + context->State = 0; + lastValid = TRUE; + lastPos = pos1; + /*drawContext = context; + DrawGeomOp( (void*)context->Op );*/ + } + break; + case OP_CIRCLE1: + case OP_CIRCLE2: + case OP_CIRCLE3: + case OP_FILLCIRCLE1: + case OP_FILLCIRCLE2: + case OP_FILLCIRCLE3: + if ( context->Op>=OP_FILLCIRCLE1 && context->Op<=OP_FILLCIRCLE3 ) + tempSegs(0).type = SEG_FILCRCL; + /*drawContext = context; + DrawGeomOp( (void*)context->Op );*/ + break; + case OP_BOX: + case OP_FILLBOX: + if ( context->Op == OP_FILLBOX ) { + pts = (coOrd*)MyMalloc( 4 * sizeof *(coOrd*)NULL ); + for ( inx=0; inx<4; inx++ ) + pts[inx] = tempSegs(inx).u.l.pos[0]; + tempSegs(0).type = SEG_FILPOLY; + tempSegs(0).u.p.cnt = 4; + tempSegs(0).u.p.pts = pts; + tempSegs(0).u.p.angle = 0.0; + tempSegs(0).u.p.orig = zero; + tempSegs_da.cnt = 1; + } + /*drawContext = context; + DrawGeomOp( (void*)context->Op );*/ + break; + case OP_POLY: + case OP_FILLPOLY: + segCnt = tempSegs_da.cnt; + context->D->funcs->options = oldOptions; + return C_CONTINUE; + } + context->Started = FALSE; + context->Changed = TRUE; + /*CheckOk();*/ + context->D->funcs->options = oldOptions; + DrawGeomOk(); + return C_TERMINATE; + + case wActionText: + if ( ((action>>8)&0xFF) == 0x0D || + ((action>>8)&0xFF) == ' ' ) { + EndPoly(context, segCnt); + context->State = 0; + } + return C_TERMINATE; + + case C_CANCEL: + oldOptions = context->D->funcs->options; + context->D->funcs->options |= wDrawOptTemp; + DrawSegs( context->D, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); + context->D->funcs->options = oldOptions; + tempSegs_da.cnt = 0; + context->message( "" ); + context->Changed = FALSE; + lastValid = FALSE; + return C_TERMINATE; + + case C_REDRAW: + oldOptions = context->D->funcs->options; + context->D->funcs->options |= wDrawOptTemp; + DrawSegs( context->D, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); + context->D->funcs->options = oldOptions; + return C_CONTINUE; + + default: + return C_CONTINUE; + } +} + + +STATUS_T DrawGeomModify( + coOrd orig, + ANGLE_T angle, + wIndex_t segCnt, + trkSeg_p segPtr, + wAction_t action, + coOrd pos, + wBool_t selected) +{ + ANGLE_T a; + coOrd p0, p1, pc; + static wIndex_t segInx; + static EPINX_T segEp; + static ANGLE_T segA1; + static int polyInx; + int inx; + DIST_T d, dd; + coOrd * newPts; + int mergePoints; + + switch ( action ) { + case C_DOWN: + segInx = -1; + DistanceSegs( orig, angle, segCnt, segPtr, &pos, &segInx ); + if (segInx == -1) + return C_ERROR; + tempSegs(0).width = segPtr[segInx].width; + tempSegs(0).color = segPtr[segInx].color; + switch ( segPtr[segInx].type ) { + case SEG_TBLEDGE: + + case SEG_STRLIN: + case SEG_DIMLIN: + case SEG_BENCH: + REORIGIN( p0, segPtr[segInx].u.l.pos[0], angle, orig ); + REORIGIN( p1, segPtr[segInx].u.l.pos[1], angle, orig ); + tempSegs(0).type = segPtr[segInx].type; + tempSegs(0).u.l.pos[0] = p0; + tempSegs(0).u.l.pos[1] = p1; + tempSegs(0).u.l.option = segPtr[segInx].u.l.option; + segA1 = FindAngle( p1, p0 ); + break; + case SEG_CRVLIN: + case SEG_FILCRCL: + REORIGIN( pc, segPtr[segInx].u.c.center, angle, orig ) + tempSegs(0).type = segPtr[segInx].type; + tempSegs(0).u.c.center = pc; + tempSegs(0).u.c.radius = segPtr[segInx].u.c.radius; + if (segPtr[segInx].u.c.a1 >= 360.0) { + tempSegs(0).u.c.a0 = 0.0; + tempSegs(0).u.c.a1 = 360.0; + } else { + tempSegs(0).u.c.a0 = NormalizeAngle( segPtr[segInx].u.c.a0+angle ); + tempSegs(0).u.c.a1 = segPtr[segInx].u.c.a1; + segA1 = NormalizeAngle( segPtr[segInx].u.c.a0 + segPtr[segInx].u.c.a1 + angle ); + PointOnCircle( &p0, pc, segPtr[segInx].u.c.radius, segPtr[segInx].u.c.a0+angle ); + PointOnCircle( &p1, pc, segPtr[segInx].u.c.radius, segPtr[segInx].u.c.a0+segPtr[segInx].u.c.a1+angle ); + } + + break; + case SEG_POLY: + case SEG_FILPOLY: + tempSegs(0).type = segPtr[segInx].type; + tempSegs(0).u.p.cnt = segPtr[segInx].u.p.cnt; + tempSegs(0).u.p.angle = 0.0; + tempSegs(0).u.p.orig = zero; + DYNARR_SET( coOrd, points_da, segPtr[segInx].u.p.cnt+1 ); + tempSegs(0).u.p.pts = &points(0); + d = 10000; + polyInx = 0; + for ( inx=0; inx<segPtr[segInx].u.p.cnt; inx++ ) { + REORIGIN( points(inx), segPtr[segInx].u.p.pts[inx], angle, orig ); + } + for ( inx=0; inx<segPtr[segInx].u.p.cnt; inx++ ) { + p0 = pos; + dd = LineDistance( &p0, points( inx==0?segPtr[segInx].u.p.cnt-1:inx-1), points( inx ) ); + if ( d > dd ) { + d = dd; + polyInx = inx; + } + } + inx = (polyInx==0?segPtr[segInx].u.p.cnt-1:polyInx-1); + d = FindDistance( points(inx), pos ); + dd = FindDistance( points(inx), points(polyInx) ); + if ( d < 0.25*dd ) { + polyInx = inx; + } else if ( d > 0.75*dd ) { + ; + } else { + tempSegs(0).u.p.cnt++; + for (inx=points_da.cnt-1; inx>polyInx; inx-- ) { + points(inx) = points(inx-1); + } +/*fprintf( stderr, "Inserting vertix before %d\n", polyInx );*/ + } + points(polyInx) = pos; + p1=p0; + break; + default: + ASSERT( FALSE ); /* CHECKME */ + case SEG_TEXT: + segInx = -1; + return C_ERROR; + } + if ( FindDistance( p0, pos ) < FindDistance( p1, pos ) ) + segEp = 0; + else { + segEp = 1; + switch ( segPtr[segInx].type ) { + case SEG_TBLEDGE: + + case SEG_STRLIN: + case SEG_DIMLIN: + case SEG_BENCH: + segA1 = NormalizeAngle( segA1 + 180.0 ); + break; + default: + ; + } + } + tempSegs_da.cnt = 1; + return C_CONTINUE; + case C_MOVE: + if (segInx == -1) + return C_ERROR; + if ( ( MyGetKeyState() & WKEY_SHIFT ) && + (tempSegs(0).type == SEG_STRLIN || tempSegs(0).type == SEG_DIMLIN || tempSegs(0).type == SEG_BENCH || tempSegs(0).type == SEG_TBLEDGE) ) { + d = FindDistance( pos, tempSegs(0).u.l.pos[1-segEp] ); + Translate( &pos, tempSegs(0).u.l.pos[1-segEp], segA1, d ); + } else if ( (MyGetKeyState() & (WKEY_SHIFT|WKEY_CTRL|WKEY_ALT)) == WKEY_CTRL ) { + OnTrack( &pos, FALSE, FALSE ); + } + switch (tempSegs(0).type) { + case SEG_TBLEDGE: + + case SEG_STRLIN: + case SEG_DIMLIN: + case SEG_BENCH: + tempSegs(0).u.l.pos[segEp] = pos; + InfoMessage( _("Length = %0.3f Angle = %0.3f"), FindDistance( tempSegs(0).u.l.pos[segEp], tempSegs(0).u.l.pos[1-segEp] ), FindAngle( tempSegs(0).u.l.pos[1-segEp], tempSegs(0).u.l.pos[segEp] ) ); + break; + pos.x -= orig.x; + pos.y -= orig.y; + pos.x -= orig.x; + pos.y -= orig.y; + Rotate( &pos, zero, -angle ); + Rotate( &pos, zero, -angle ); + case SEG_CRVLIN: + case SEG_FILCRCL: + if (tempSegs(0).u.c.a1 >= 360.0) { + tempSegs(0).u.c.radius = FindDistance( tempSegs(0).u.c.center, pos ); + } else { + a = FindAngle( tempSegs(0).u.c.center, pos ); + if (segEp==0) { + tempSegs(0).u.c.a1 = NormalizeAngle(segA1-a); + tempSegs(0).u.c.a0 = a; + } else { + tempSegs(0).u.c.a1 = NormalizeAngle(a-tempSegs(0).u.c.a0); + } + } + break; + case SEG_POLY: + case SEG_FILPOLY: + points(polyInx) = pos; + break; + default: + ; + } + tempSegs_da.cnt = 1; + return C_CONTINUE; + case C_UP: + if (segInx == -1) + return C_CONTINUE; + switch (tempSegs(0).type) { + case SEG_TBLEDGE: + + case SEG_STRLIN: + case SEG_DIMLIN: + case SEG_BENCH: + pos = tempSegs(0).u.l.pos[segEp]; + pos.x -= orig.x; + pos.y -= orig.y; + Rotate( &pos, zero, -angle ); + segPtr[segInx].u.l.pos[segEp] = pos; + break; + case SEG_CRVLIN: + case SEG_FILCRCL: + if ( tempSegs(0).u.c.a1 >= 360.0 ) { + segPtr[segInx].u.c.radius = tempSegs(0).u.c.radius; + } else { + a = FindAngle( tempSegs(0).u.c.center, pos ); + a = NormalizeAngle( a-angle ); + segPtr[segInx].u.c.a1 = tempSegs(0).u.c.a1; + if (segEp == 0) { + segPtr[segInx].u.c.a0 = a; + } + } + break; + case SEG_POLY: + case SEG_FILPOLY: + mergePoints = FALSE; + if ( IsClose( FindDistance( pos, points( polyInx==0?tempSegs(0).u.p.cnt-1:polyInx-1 ) ) ) || + IsClose( FindDistance( pos, points( (polyInx==tempSegs(0).u.p.cnt-1)?0:polyInx+1 ) ) ) ) { + mergePoints = TRUE; + if (segPtr[segInx].u.p.cnt <= 3) { + ErrorMessage( MSG_POLY_SHAPES_3_SIDES ); + break; + } + } + + newPts = (coOrd*)MyMalloc( tempSegs(0).u.p.cnt * sizeof *(coOrd*)0 ); + memcpy( newPts, segPtr[segInx].u.p.pts, (segPtr[segInx].u.p.cnt) * sizeof *(coOrd*)0 ); + segPtr[segInx].u.p.pts = newPts; + + if ( tempSegs(0).u.p.cnt > segPtr[segInx].u.p.cnt ) { + ASSERT( tempSegs(0).u.p.cnt == segPtr[segInx].u.p.cnt+1 ); + for (inx=tempSegs(0).u.p.cnt-1; inx>polyInx; inx--) + segPtr[segInx].u.p.pts[inx] = segPtr[segInx].u.p.pts[inx-1]; + segPtr[segInx].u.p.cnt++; + } + + pos = points(polyInx); + if ( mergePoints ) { + for (inx=polyInx+1; inx<points_da.cnt; inx++) + segPtr[segInx].u.p.pts[inx-1] = segPtr[segInx].u.p.pts[inx]; + segPtr[segInx].u.p.cnt--; +/*fprintf( stderr, "Merging with vertix %d\n", polyInx );*/ + break; + } + pos.x -= orig.x; + pos.y -= orig.y; + Rotate( &pos, zero, -angle ); + segPtr[segInx].u.p.pts[polyInx] = pos; + break; + default: + ; + } + return C_TERMINATE; + default: + ; + } + return C_ERROR; +} |