diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2020-08-08 11:53:00 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2020-08-08 11:53:00 +0200 |
commit | b623f5953691b2a0614e6f1f4def86bdbb9a4113 (patch) | |
tree | 18102bd36f7e22eb2ba2b9f880e4cb29346f4cb8 /app/bin/cdraw.c | |
parent | 359b557176b9bb2ff1aed2082641eed39c358d0d (diff) |
New upstream version 5.2.0Beta2.1upstream/5.2.0Beta2.1
Diffstat (limited to 'app/bin/cdraw.c')
-rw-r--r-- | app/bin/cdraw.c | 1814 |
1 files changed, 1680 insertions, 134 deletions
diff --git a/app/bin/cdraw.c b/app/bin/cdraw.c index 9bddcaf..6bb4c4a 100644 --- a/app/bin/cdraw.c +++ b/app/bin/cdraw.c @@ -23,6 +23,7 @@ #include <math.h> #include <stdint.h> #include <string.h> +#include "wlib.h" #include "ccurve.h" #include "cbezier.h" @@ -37,7 +38,31 @@ extern TRKTYP_T T_BZRLIN; -extern void wSetSelectedFontSize(int size); +static wMenu_p drawModDelMI; +static wMenu_p drawModLinMI; +static wMenuPush_p drawModDel; +static wMenuPush_p drawModSmooth; +static wMenuPush_p drawModVertex; +static wMenuPush_p drawModRound; +static wMenuPush_p drawModriginMode; +static wMenuPush_p drawModPointsMode; +static wMenuPush_p drawModOrigin; +static wMenuPush_p drawModLast; +static wMenuPush_p drawModCenter; +static wMenuPush_p drawModClose; +static wMenuPush_p drawModOpen; +static wMenuPush_p drawModFill; +static wMenuPush_p drawModEmpty; +static wMenuPush_p drawModSolid; +static wMenuPush_p drawModDot; +static wMenuPush_p drawModDash; +static wMenuPush_p drawModDashDot; +static wMenuPush_p drawModDashDotDot; +static wMenuPush_p drawModCenterDot; +static wMenuPush_p drawModPhantom; + + +extern void wSetSelectedFontSize(wFontSize_t size); static long fontSizeList[] = { 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 24, 28, 32, 36, @@ -111,7 +136,7 @@ EXPORT void UpdateFontSizeList( *fontSizeR = fontSize; /* inform gtkfont dialog from change */ - wSetSelectedFontSize((int)fontSize); + wSetSelectedFontSize((wFontSize_t)fontSize); /*LoadFontSizeList( list, *fontSizeR );*/ } else { sprintf( message, "%ld", *fontSizeR ); @@ -128,9 +153,11 @@ EXPORT void UpdateFontSizeList( * */ + struct extraData { coOrd orig; ANGLE_T angle; + drawLineType_e lineType; wIndex_t segCnt; trkSeg_t segs[1]; }; @@ -167,12 +194,13 @@ static track_p MakeDrawFromSeg1( xx->orig = pos; xx->angle = angle; xx->segCnt = 1; + xx->lineType = DRAWLINESOLID; memcpy( xx->segs, sp, sizeof *(trkSeg_p)0 ); if (xx->segs[0].type == SEG_POLY || - xx->segs[0].type == SEG_FILPOLY) { - xx->segs[0].u.p.pts = (coOrd*)MyMalloc( (sp->u.p.cnt) * sizeof (coOrd) ); - memcpy(xx->segs[0].u.p.pts, sp->u.p.pts, sp->u.p.cnt * sizeof (coOrd) ); + xx->segs[0].type == SEG_FILPOLY ) { + xx->segs[0].u.p.pts = (pts_t*)MyMalloc( (sp->u.p.cnt) * sizeof (pts_t) ); + memcpy(xx->segs[0].u.p.pts, sp->u.p.pts, sp->u.p.cnt * sizeof (pts_t) ); } if (xx->segs[0].type == SEG_TEXT) { xx->segs[0].u.t.string = MyStrdup(sp->u.t.string); @@ -189,6 +217,254 @@ EXPORT track_p MakeDrawFromSeg( return MakeDrawFromSeg1( 0, pos, angle, sp ); } +int SliceCuts(ANGLE_T a, DIST_T radius) { + double Error = 0.05; + double Error_angle = acos(1-(Error/fabs(radius))); + if (Error_angle <0.0001) return 0; + return (int)(floor(D2R(a)/(2*Error_angle))); +} + +/* Only straight, curved and PolyLine */ +EXPORT track_p MakePolyLineFromSegs( + coOrd pos, + ANGLE_T angle, + dynArr_t * segsArr) +{ + struct extraData * xx; + track_p trk; + trk = NewTrack( 0, T_DRAW, 0, sizeof *xx ); + xx = GetTrkExtraData( trk ); + xx->orig = pos; + xx->angle = angle; + xx->lineType = DRAWLINESOLID; + xx->segCnt = 1; + xx->segs[0].type = SEG_POLY; + xx->segs[0].width = 0; + xx->segs[0].u.p.polyType = POLYLINE; + xx->segs[0].color = wDrawColorBlack; + coOrd last; + BOOL_T first = TRUE; + int cnt = 0; + for (int i=0;i<segsArr->cnt;i++) { + trkSeg_p sp = &DYNARR_N(trkSeg_t,*segsArr,i); + if (sp->type == SEG_BEZLIN || sp->type == SEG_BEZTRK ) { + for (int j=0;j<sp->bezSegs.cnt;j++) { + trkSeg_p spb = &DYNARR_N(trkSeg_t,sp->bezSegs,j); + if (spb->type == SEG_STRLIN || spb->type == SEG_STRTRK) { + if (!first && IsClose(FindDistance(spb->u.l.pos[0], last))) + cnt++; + else + cnt=cnt+2; + last = spb->u.l.pos[1]; + first = FALSE; + } + else if (spb->type == SEG_CRVLIN || spb->type == SEG_CRVTRK) { + coOrd this; + if (spb->u.c.radius >= 0.0) + Translate(&this, spb->u.c.center, spb->u.c.a0, fabs(spb->u.c.radius)); + else + Translate(&this, spb->u.c.center, spb->u.c.a0+spb->u.c.a1, fabs(spb->u.c.radius)); + if (first || !IsClose(FindDistance(this, last))) { + cnt++; //Add first point + } + cnt += 1 + SliceCuts(spb->u.c.a1,spb->u.c.radius); + if (spb->u.c.radius >= 0.0) + Translate(&last, spb->u.c.center, spb->u.c.a0+spb->u.c.a1, fabs(spb->u.c.radius)); + else + Translate(&last, spb->u.c.center, spb->u.c.a0, fabs(spb->u.c.radius)); + first = FALSE; + } + } + } + else if (sp->type == SEG_STRLIN || sp->type == SEG_STRTRK) { + if (!first && IsClose(FindDistance(sp->u.l.pos[0], last))) + cnt++; + else + cnt=cnt+2; + last = sp->u.l.pos[1]; + first = FALSE; + } + else if (sp->type == SEG_CRVLIN || sp->type == SEG_CRVTRK) { + coOrd this; + if (sp->u.c.radius >= 0.0) + Translate(&this, sp->u.c.center, sp->u.c.a0, fabs(sp->u.c.radius)); + else + Translate(&this, sp->u.c.center, sp->u.c.a0+sp->u.c.a1, fabs(sp->u.c.radius)); + if (first || !IsClose(FindDistance(this, last))) { + cnt++; //Add first point + } + cnt += 1+ SliceCuts(sp->u.c.a1,sp->u.c.radius); + if (sp->u.c.radius >= 0.0) + Translate(&last, sp->u.c.center, sp->u.c.a0+sp->u.c.a1, fabs(sp->u.c.radius)); + else + Translate(&last, sp->u.c.center, sp->u.c.a0, fabs(sp->u.c.radius)); + first = FALSE; + } + else if (sp->type == SEG_POLY) { + if (!first && IsClose(FindDistance(sp->u.p.pts[0].pt, last))) + cnt = cnt + sp->u.p.cnt-1; + else + cnt = cnt + sp->u.p.cnt; + last = sp->u.p.pts[sp->u.p.cnt-1].pt; + first = FALSE; + } + } + xx->segs[0].u.p.cnt = cnt; + xx->segs[0].u.p.pts = (pts_t*)MyMalloc( (cnt) * sizeof (pts_t) ); + first = TRUE; + int j =0; + for (int i=0;i<segsArr->cnt;i++) { + trkSeg_p sp = &DYNARR_N(trkSeg_t,*segsArr,i); + if (sp->type == SEG_BEZLIN || sp->type == SEG_BEZTRK ) { + for (int l=0;l<sp->bezSegs.cnt;l++) { + trkSeg_p spb = &DYNARR_N(trkSeg_t,sp->bezSegs,l); + if (spb->type == SEG_STRLIN || spb->type == SEG_STRTRK) { + if (first || !IsClose(FindDistance(spb->u.l.pos[0], last))) { + xx->segs[0].u.p.pts[j].pt = spb->u.l.pos[0]; + xx->segs[0].u.p.pts[j].pt_type = wPolyLineStraight; + j++; + } + xx->segs[0].u.p.pts[j].pt = spb->u.l.pos[1]; + xx->segs[0].u.p.pts[j].pt_type = wPolyLineStraight; + last = xx->segs[0].u.p.pts[j].pt; + j ++; + first = FALSE; + } + if (spb->type == SEG_CRVLIN || spb->type == SEG_CRVTRK) { + coOrd this; + if (spb->u.c.radius>=0.0) + Translate(&this, spb->u.c.center, spb->u.c.a0, fabs(spb->u.c.radius)); + else + Translate(&this, spb->u.c.center, spb->u.c.a0+spb->u.c.a1, fabs(spb->u.c.radius)); + if (first || !IsClose(FindDistance(this, last))) { + xx->segs[0].u.p.pts[j].pt= this; + xx->segs[0].u.p.pts[j].pt_type = wPolyLineStraight; + j++; + } + int slices = SliceCuts(spb->u.c.a1,spb->u.c.radius); + for (int k=1; k<slices;k++) { + if (spb->u.c.radius>=0.0) + Translate(&xx->segs[0].u.p.pts[j].pt, spb->u.c.center, spb->u.c.a0+(k*(spb->u.c.a1/(slices))), fabs(spb->u.c.radius)); + else + Translate(&xx->segs[0].u.p.pts[j].pt, spb->u.c.center, spb->u.c.a0+((slices-k)*(spb->u.c.a1/(slices))), fabs(spb->u.c.radius)); + xx->segs[0].u.p.pts[j].pt_type = wPolyLineSmooth; + j++; + } + if (spb->u.c.radius>=0.0) + Translate(&xx->segs[0].u.p.pts[j].pt, spb->u.c.center, spb->u.c.a0+spb->u.c.a1, fabs(spb->u.c.radius)); + else + Translate(&xx->segs[0].u.p.pts[j].pt, spb->u.c.center, spb->u.c.a0, fabs(spb->u.c.radius)); + + xx->segs[0].u.p.pts[j].pt_type = wPolyLineStraight; + last = xx->segs[0].u.p.pts[j].pt; + j++; + first = FALSE; + } + } + } + if (sp->type == SEG_STRLIN || sp->type == SEG_STRTRK) { + if (first || !IsClose(FindDistance(sp->u.l.pos[0], last))) { + xx->segs[0].u.p.pts[j].pt = sp->u.l.pos[0]; + xx->segs[0].u.p.pts[j].pt_type = wPolyLineStraight; + j++; + } + xx->segs[0].u.p.pts[j].pt = last = sp->u.l.pos[1]; + xx->segs[0].u.p.pts[j].pt_type = wPolyLineStraight; + last = xx->segs[0].u.p.pts[j].pt; + j++; + first = FALSE; + } + if (sp->type == SEG_CRVLIN || sp->type == SEG_CRVTRK) { + coOrd this; + if (sp->u.c.radius>0) + Translate(&this, sp->u.c.center, sp->u.c.a0, fabs(sp->u.c.radius)); + else + Translate(&this, sp->u.c.center, sp->u.c.a0+sp->u.c.a1, fabs(sp->u.c.radius)); + if (first || !IsClose(FindDistance(this, last))) { + xx->segs[0].u.p.pts[j].pt= this; + xx->segs[0].u.p.pts[j].pt_type = wPolyLineStraight; + j++; + } + int slices = SliceCuts(sp->u.c.a1,sp->u.c.radius); + + for (int k=1; k<slices;k++) { + if (sp->u.c.radius>0) + Translate(&xx->segs[0].u.p.pts[j].pt, sp->u.c.center, sp->u.c.a0+(k*(sp->u.c.a1/(slices))), fabs(sp->u.c.radius)); + else + Translate(&xx->segs[0].u.p.pts[j].pt, sp->u.c.center, sp->u.c.a0+((slices-k)*(sp->u.c.a1/(slices))), fabs(sp->u.c.radius)); + xx->segs[0].u.p.pts[j].pt_type = wPolyLineSmooth; + j++; + } + if (sp->u.c.radius>0) + Translate(&xx->segs[0].u.p.pts[j].pt, sp->u.c.center, sp->u.c.a0+sp->u.c.a1, fabs(sp->u.c.radius)); + else + Translate(&xx->segs[0].u.p.pts[j].pt, sp->u.c.center, sp->u.c.a0, fabs(sp->u.c.radius)); + + xx->segs[0].u.p.pts[j].pt_type = wPolyLineStraight; + last = xx->segs[0].u.p.pts[j].pt; + j++; + first = FALSE; + } + if (sp->type == SEG_POLY) { + if (first || !IsClose(FindDistance(sp->u.p.pts[0].pt, last))) { + xx->segs[0].u.p.pts[j] = sp->u.p.pts[0]; + j++; + } + memcpy(&xx->segs[0].u.p.pts[j],&sp->u.p.pts[1], (sp->u.p.cnt-1) * sizeof (pts_t)); + last = xx->segs[0].u.p.pts[sp->u.p.cnt-1].pt; + j +=sp->u.p.cnt-1; + first = FALSE; + } + ASSERT(j<=cnt); + + } + xx->segs[0].u.p.cnt = j; + + if (IsClose(FindDistance(xx->segs[0].u.p.pts[0].pt,xx->segs[0].u.p.pts[xx->segs[0].u.p.cnt-1].pt))) { + xx->segs[0].u.p.polyType = FREEFORM; + xx->segs[0].u.p.cnt = xx->segs[0].u.p.cnt-1; + } + + ComputeDrawBoundingBox( trk ); + return trk; +} + + +static dynArr_t anchors_da; +#define anchors(N) DYNARR_N(trkSeg_t,anchors_da,N) + +void static CreateOriginAnchor(coOrd origin, wBool_t trans_selected) { + double d = tempD.scale*0.15; + DYNARR_APPEND(trkSeg_t,anchors_da,2); + int i = anchors_da.cnt-1; + coOrd p0,p1; + Translate(&p0,origin,0,d*4); + Translate(&p1,origin,0,-d*4); + 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).width = 0; + DYNARR_APPEND(trkSeg_t,anchors_da,1); + Translate(&p0,origin,90,d*4); + Translate(&p1,origin,90,-d*4); + i = anchors_da.cnt-1; + 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).width = 0; +} + +EXPORT void DrawOriginAnchor(track_p trk) { + if (!trk || GetTrkType(trk) != T_DRAW) return; + struct extraData * xx = GetTrkExtraData(trk); + if ((xx->orig.x != 0.0) || (xx->orig.y !=0.0) ) { + DYNARR_RESET(trkSeg_t,anchors_da); + CreateOriginAnchor(xx->orig,FALSE); + DrawSegs(&tempD, zero, 0.0, anchors_da.ptr, anchors_da.cnt, trackGauge, wDrawColorBlue); + } +} @@ -204,15 +480,27 @@ static DIST_T DistanceDraw( track_p t, coOrd * p ) static struct { - coOrd endPt[2]; + coOrd endPt[4]; + coOrd origin; + coOrd oldOrigin; + coOrd oldE0; + coOrd oldE1; FLOAT_T length; + FLOAT_T height; + FLOAT_T width; coOrd center; DIST_T radius; ANGLE_T angle0; ANGLE_T angle1; ANGLE_T angle; + ANGLE_T rotate_angle; + ANGLE_T oldAngle; long pointCount; long lineWidth; + BOOL_T boxed; + BOOL_T filled; + BOOL_T open; + BOOL_T lock_origin; wDrawColor color; wIndex_t benchChoice; wIndex_t benchOrient; @@ -221,21 +509,31 @@ static struct { wIndex_t fontSizeInx; char text[STR_LONG_SIZE]; unsigned int layer; - char polyType[STR_SIZE]; + wIndex_t lineType; } drawData; -typedef enum { E0, E1, CE, RA, LN, AL, A1, A2, VC, LW, CO, BE, OR, DS, TP, TA, TS, TX, PV, LY, PT } drawDesc_e; +typedef enum { E0, E1, PP, CE, AL, A1, A2, RD, LN, HT, WT, LK, OI, RA, VC, LW, LT, CO, FL, OP, BX, BE, OR, DS, TP, TA, TS, TX, PV, LY } drawDesc_e; static descData_t drawDesc[] = { /*E0*/ { DESC_POS, N_("End Pt 1: X,Y"), &drawData.endPt[0] }, /*E1*/ { DESC_POS, N_("End Pt 2: X,Y"), &drawData.endPt[1] }, +/*PP*/ { DESC_POS, N_("First Point: X,Y"), &drawData.endPt[0] }, /*CE*/ { DESC_POS, N_("Center: X,Y"), &drawData.center }, -/*RA*/ { DESC_DIM, N_("Radius"), &drawData.radius }, -/*LN*/ { DESC_DIM, N_("Length"), &drawData.length }, /*AL*/ { DESC_FLOAT, N_("Angle"), &drawData.angle }, /*A1*/ { DESC_ANGLE, N_("CCW Angle"), &drawData.angle0 }, /*A2*/ { DESC_ANGLE, N_("CW Angle"), &drawData.angle1 }, +/*RD*/ { DESC_DIM, N_("Radius"), &drawData.radius }, +/*LN*/ { DESC_DIM, N_("Length"), &drawData.length }, +/*HT*/ { DESC_DIM, N_("Height"), &drawData.height }, +/*WT*/ { DESC_DIM, N_("Width"), &drawData.width }, +/*LK*/ { DESC_BOXED, N_("Keep Origin Relative"), &drawData.lock_origin}, +/*OI*/ { DESC_POS, N_("Rot Origin: X,Y"), &drawData.origin }, +/*RA*/ { DESC_FLOAT, N_("Rotate Angle"), &drawData.angle }, /*VC*/ { DESC_LONG, N_("Point Count"), &drawData.pointCount }, /*LW*/ { DESC_LONG, N_("Line Width"), &drawData.lineWidth }, +/*LT*/ { DESC_LIST, N_("Line Type"), &drawData.lineType }, /*CO*/ { DESC_COLOR, N_("Color"), &drawData.color }, +/*FL*/ { DESC_BOXED, N_("Filled"), &drawData.filled }, +/*OP*/ { DESC_BOXED, N_("Open End"), &drawData.open }, +/*BX*/ { DESC_BOXED, N_("Boxed"), &drawData.boxed }, /*BE*/ { DESC_LIST, N_("Lumber"), &drawData.benchChoice }, /*OR*/ { DESC_LIST, N_("Orientation"), &drawData.benchOrient }, /*DS*/ { DESC_LIST, N_("Size"), &drawData.dimenSize }, @@ -245,9 +543,8 @@ static descData_t drawDesc[] = { /*TX*/ { DESC_TEXT, N_("Text"), &drawData.text }, /*PV*/ { DESC_PIVOT, N_("Pivot"), &drawData.pivot }, /*LY*/ { DESC_LAYER, N_("Layer"), &drawData.layer }, -/*PT*/ { DESC_STRING, N_("Type"), &drawData.polyType }, { DESC_NULL } }; -int drawSegInx; +static int drawSegInx; #define UNREORIGIN( Q, P, A, O ) { \ (Q) = (P); \ @@ -257,6 +554,23 @@ int drawSegInx; Rotate( &(Q), zero, -(A) ); \ } +/* + * Notes - + * + * In V5.1, Origin was always {0,0} and Angle 0.0 after editing a Draw object. + * This did not allow for the use of the objects in other contexts (such as Signal Arms). + * + * In V5.2 - + * + * OI - Origin will be adjusted if it is locked to remain relative to the end point - this equally applies when moving the object points. + * If not locked, the object points will be set relative to the new origin value, + * so that the object remains at the same place as the user specifies. + * If the edit starts with origin {0,0}, it will be set unlocked, otherwise set locked. + * + * AL- Angle will be set to 0.0 when the object is modified. The points of the objects will be rotated so that + * rotated and adjusted so they don't need rotation to lie where the user left them. + * + */ static void UpdateDraw( track_p trk, int inx, descData_p descUpd, BOOL_T final ) { struct extraData *xx = GetTrkExtraData(trk); @@ -271,9 +585,9 @@ static void UpdateDraw( track_p trk, int inx, descData_p descUpd, BOOL_T final ) if (segPtr->type != SEG_TEXT) return; else inx = TX; //Always look at TextField for SEG_TEXT on "Done" } - MainRedraw(); - MapRedraw(); UndrawNewTrack( trk ); + coOrd pt; + coOrd off; switch ( inx ) { case LW: segPtr->width = drawData.lineWidth/mainD.dpi; @@ -284,37 +598,251 @@ static void UpdateDraw( track_p trk, int inx, descData_p descUpd, BOOL_T final ) case E0: case E1: if ( inx == E0 ) { - UNREORIGIN( segPtr->u.l.pos[0], drawData.endPt[0], xx->angle, xx->orig ); - } else { - UNREORIGIN( segPtr->u.l.pos[1], drawData.endPt[1], xx->angle, xx->orig ); + coOrd off; + off.x = drawData.endPt[0].x - drawData.oldE0.x; + off.y = drawData.endPt[0].y - drawData.oldE0.y; + if (drawData.lock_origin) { + xx->orig.x +=off.x; + xx->orig.y +=off.y; + drawDesc[OI].mode |= DESC_CHANGE; + } else { + switch(segPtr->type) { //E0 does not alter length - translates + case SEG_STRLIN: + case SEG_DIMLIN: + case SEG_BENCH: + case SEG_TBLEDGE: + UNREORIGIN( segPtr->u.l.pos[0], drawData.endPt[0], xx->angle, xx->orig ); + drawData.endPt[1].x = off.x+drawData.endPt[1].x; + drawData.endPt[1].y = off.y+drawData.endPt[1].y; + UNREORIGIN( segPtr->u.l.pos[1], drawData.endPt[1], xx->angle, xx->orig ); + drawDesc[E1].mode |= DESC_CHANGE; + break; + case SEG_CRVLIN: + case SEG_FILCRCL: + UNREORIGIN( segPtr->u.c.center, drawData.endPt[0], xx->angle, xx->orig ); + break; + case SEG_TEXT: + UNREORIGIN( segPtr->u.t.pos, drawData.endPt[0], xx->angle, xx->orig ); + break; + case SEG_POLY: + case SEG_FILPOLY: + break; //Note not used by POLYGONS + default:; + } + } + } else { //E1 - alters length + off.x = drawData.endPt[1].x - drawData.oldE1.x; + off.y = drawData.endPt[1].y - drawData.oldE1.y; + drawDesc[E1].mode |= DESC_CHANGE; + if (drawData.lock_origin) { + xx->orig.x +=off.x; + xx->orig.y +=off.y; + drawDesc[OI].mode |= DESC_CHANGE; + } else { + UNREORIGIN( segPtr->u.l.pos[1], drawData.endPt[1], xx->angle, xx->orig ); + } } drawData.length = FindDistance( drawData.endPt[0], drawData.endPt[1] ); - drawData.angle = FindAngle( drawData.endPt[0], drawData.endPt[1] ); drawDesc[LN].mode |= DESC_CHANGE; - drawDesc[AL].mode |= DESC_CHANGE; break; - case LN: - case AL: - if ( segPtr->type == SEG_CRVLIN && inx == AL ) { - if ( drawData.angle <= 0.0 || drawData.angle >= 360.0 ) { - ErrorMessage( MSG_CURVE_OUT_OF_RANGE ); - drawData.angle = segPtr->u.c.a1; - drawDesc[AL].mode |= DESC_CHANGE; + case OI: + off.x = drawData.origin.x - drawData.oldOrigin.x; + off.y = drawData.origin.y - drawData.oldOrigin.y; + xx->orig = drawData.origin; + if (!drawData.lock_origin) { + switch(segPtr->type) { + case SEG_POLY: + case SEG_FILPOLY: + for (int i=0;i<segPtr->u.p.cnt;i++) { + REORIGIN( pt, segPtr->u.p.pts[i].pt, xx->angle, drawData.oldOrigin); + UNREORIGIN( segPtr->u.p.pts[i].pt, pt, xx->angle, xx->orig ); + } break; + case SEG_STRLIN: + case SEG_DIMLIN: + case SEG_BENCH: + case SEG_TBLEDGE: + for (int i=0;i<2;i++) { + UNREORIGIN( segPtr->u.l.pos[i], drawData.endPt[i], xx->angle, xx->orig ); + } + break; + case SEG_CRVLIN: + case SEG_FILCRCL: + UNREORIGIN( segPtr->u.c.center, drawData.center, xx->angle, xx->orig ); + break; + case SEG_TEXT: + UNREORIGIN( segPtr->u.t.pos, drawData.endPt[0], xx->angle, xx->orig ); + break; + default:; } } else { - if ( drawData.length <= minLength ) { - ErrorMessage( MSG_OBJECT_TOO_SHORT ); - if ( segPtr->type != SEG_CRVLIN ) { - drawData.length = FindDistance( drawData.endPt[0], drawData.endPt[1] ); + drawData.endPt[0].x += off.x; + drawData.endPt[0].y += off.y; + switch(segPtr->type) { + case SEG_STRLIN: + case SEG_DIMLIN: + case SEG_BENCH: + case SEG_TBLEDGE: + drawDesc[E0].mode |= DESC_CHANGE; + UNREORIGIN( segPtr->u.l.pos[0], drawData.endPt[0], xx->angle, xx->orig ); + drawData.endPt[1].x = off.x+drawData.endPt[1].x; + drawData.endPt[1].y = off.y+drawData.endPt[1].y; + UNREORIGIN( segPtr->u.l.pos[1], drawData.endPt[1], xx->angle, xx->orig ); + drawDesc[E1].mode |= DESC_CHANGE; + break; + case SEG_CRVLIN: + case SEG_FILCRCL: + UNREORIGIN( segPtr->u.c.center, drawData.endPt[0], xx->angle, xx->orig ); + drawDesc[E0].mode |= DESC_CHANGE; + break; + case SEG_TEXT: + UNREORIGIN( segPtr->u.t.pos, drawData.endPt[0], xx->angle, xx->orig ); + drawDesc[E0].mode |= DESC_CHANGE; + break; + case SEG_POLY: + case SEG_FILPOLY: + for (int i=0;i<segPtr->u.p.cnt;i++) { + REORIGIN( pt, segPtr->u.p.pts[i].pt, xx->angle, drawData.oldOrigin); + pt.x += off.x; + pt.y += off.y; + UNREORIGIN( segPtr->u.p.pts[i].pt, pt, xx->angle, xx->orig ); + } + drawDesc[PP].mode |= DESC_CHANGE; + break; + default:; + } + } + break; + case HT: + case WT: + if ((segPtr->type == SEG_POLY) || (segPtr->type == SEG_FILPOLY)) { + if (segPtr->u.p.polyType == RECTANGLE) { + if (inx == HT) { + ANGLE_T angle = NormalizeAngle(FindAngle(drawData.endPt[0],drawData.endPt[3])); + Translate( &drawData.endPt[3], drawData.endPt[0], angle, drawData.height); + UNREORIGIN( segPtr->u.p.pts[3].pt, drawData.endPt[3], xx->angle, xx->orig ); + Translate( &drawData.endPt[2], drawData.endPt[1], angle, drawData.height); + UNREORIGIN( segPtr->u.p.pts[2].pt, drawData.endPt[2], xx->angle, xx->orig ); } else { - drawData.length = fabs(segPtr->u.c.radius)*2*M_PI*segPtr->u.c.a1/360.0; + ANGLE_T angle = NormalizeAngle(FindAngle(drawData.endPt[0],drawData.endPt[1]));; + Translate( &drawData.endPt[1], drawData.endPt[0], angle, drawData.width); + UNREORIGIN( segPtr->u.p.pts[1].pt, drawData.endPt[1], xx->angle, xx->orig ); + Translate( &drawData.endPt[2], drawData.endPt[3], angle, drawData.width); + UNREORIGIN( segPtr->u.p.pts[2].pt, drawData.endPt[2], xx->angle, xx->orig ); } - drawDesc[LN].mode |= DESC_CHANGE; + drawDesc[E0].mode |= DESC_CHANGE; + } + } + break; + case RA:; + ANGLE_T angle = NormalizeAngle(drawData.rotate_angle); + switch(segPtr->type) { + case SEG_POLY: + case SEG_FILPOLY: + for (int i=0;i<segPtr->u.p.cnt;i++) { + REORIGIN(pt,segPtr->u.p.pts[i].pt, angle, xx->orig); + if (i == 0) drawData.endPt[0] = pt; + UNREORIGIN(segPtr->u.p.pts[i].pt, pt, 0.0, xx->orig); + } + drawDesc[PP].mode |= DESC_CHANGE; break; + case SEG_CRVLIN:; + coOrd end0, end1; + Translate(&end0,segPtr->u.c.center,segPtr->u.c.a0,segPtr->u.c.radius); + Translate(&end1,segPtr->u.c.center,segPtr->u.c.a0+segPtr->u.c.a1,segPtr->u.c.radius); + REORIGIN(end0, end0, angle, xx->orig ); + REORIGIN(end1, end1, angle, xx->orig ); + REORIGIN( drawData.center,segPtr->u.c.center, angle, xx->orig ); + drawData.angle0 = FindAngle( drawData.center, end0); + drawData.angle1 = FindAngle( drawData.center, end1); + drawDesc[CE].mode |= DESC_CHANGE; + drawDesc[A1].mode |= DESC_CHANGE; + drawDesc[A2].mode |= DESC_CHANGE; + /*no break*/ + case SEG_FILCRCL: + REORIGIN( drawData.center,segPtr->u.c.center, angle, xx->orig ); + UNREORIGIN( segPtr->u.c.center, drawData.center, 0.0, xx->orig); //Remove angle + drawDesc[CE].mode |= DESC_CHANGE; + break; + case SEG_STRLIN: + case SEG_DIMLIN: + case SEG_BENCH: + case SEG_TBLEDGE: + for (int i=0;i<2;i++) { + REORIGIN( drawData.endPt[i], segPtr->u.l.pos[i], angle, xx->orig ); + UNREORIGIN(segPtr->u.l.pos[i], drawData.endPt[i], 0.0, xx->orig ); + } + drawDesc[E0].mode |= DESC_CHANGE; + drawDesc[E1].mode |= DESC_CHANGE; + break; + case SEG_TEXT: + + break; + default:; + } + xx->angle = drawData.rotate_angle = 0.0; + drawDesc[RA].mode |= DESC_CHANGE; + break; + case AL:; + angle = NormalizeAngle(drawData.angle); + switch(segPtr->type) { + case SEG_POLY: + case SEG_FILPOLY: + break; //Doesn't Use + case SEG_CRVLIN: + switch ( drawData.pivot ) { + case DESC_PIVOT_FIRST: + segPtr->u.c.a1 = drawData.angle; + drawData.angle1 = NormalizeAngle( drawData.angle0+segPtr->u.c.a1 ); + drawDesc[A2].mode |= DESC_CHANGE; + break; + case DESC_PIVOT_SECOND: + segPtr->u.c.a0 = NormalizeAngle( segPtr->u.c.a1+segPtr->u.c.a0-drawData.angle); + segPtr->u.c.a1 = drawData.angle; + drawData.angle0 = NormalizeAngle( segPtr->u.c.a0+xx->angle ); + drawData.angle1 = NormalizeAngle( drawData.angle0+segPtr->u.c.a1 ); + drawDesc[A1].mode |= DESC_CHANGE; + drawDesc[A2].mode |= DESC_CHANGE; + break; + case DESC_PIVOT_MID: + segPtr->u.c.a0 = NormalizeAngle( segPtr->u.c.a0+segPtr->u.c.a1/2.0-drawData.angle/2.0); + segPtr->u.c.a1 = drawData.angle; + drawData.angle0 = NormalizeAngle( segPtr->u.c.a0+xx->angle ); + drawData.angle1 = NormalizeAngle( drawData.angle0+segPtr->u.c.a1 ); + drawDesc[A1].mode |= DESC_CHANGE; + drawDesc[A2].mode |= DESC_CHANGE; + break; + default: + break; + } + break; + case SEG_FILCRCL: + break; //Doesn't Use + case SEG_STRLIN: + case SEG_DIMLIN: + case SEG_BENCH: + case SEG_TBLEDGE: + Translate(&drawData.endPt[1],drawData.endPt[0],angle,drawData.length); + UNREORIGIN(segPtr->u.l.pos[1], drawData.endPt[1], xx->angle, xx->orig ); + drawDesc[E1].mode |= DESC_CHANGE; + break; + case SEG_TEXT: + break; //Doesnt Use + default:; + } + break; + case LN: + if ( drawData.length <= minLength ) { + ErrorMessage( MSG_OBJECT_TOO_SHORT ); + if ( segPtr->type != SEG_CRVLIN ) { + drawData.length = FindDistance( drawData.endPt[0], drawData.endPt[1] ); + } else { + drawData.length = fabs(segPtr->u.c.radius)*2*M_PI*segPtr->u.c.a1/360.0; } + drawDesc[LN].mode |= DESC_CHANGE; + break; } - if ( segPtr->type != SEG_CRVLIN ) { + if ( segPtr->type != SEG_CRVLIN ) { switch ( drawData.pivot ) { case DESC_PIVOT_FIRST: Translate( &drawData.endPt[1], drawData.endPt[0], drawData.angle, drawData.length ); @@ -340,6 +868,7 @@ static void UpdateDraw( track_p trk, int inx, descData_p descUpd, BOOL_T final ) break; } } else { + if ( drawData.angle < 0.0 || drawData.angle >= 360.0 ) { ErrorMessage( MSG_CURVE_OUT_OF_RANGE ); drawData.angle = segPtr->u.c.a1; @@ -357,13 +886,44 @@ static void UpdateDraw( track_p trk, int inx, descData_p descUpd, BOOL_T final ) case CE: UNREORIGIN( segPtr->u.c.center, drawData.center, xx->angle, xx->orig ); break; - case RA: + case RD: + if ( drawData.pivot == DESC_PIVOT_FIRST ) { + Translate( &segPtr->u.c.center, segPtr->u.c.center, segPtr->u.c.a0, segPtr->u.c.radius-drawData.radius ); + } else if ( drawData.pivot == DESC_PIVOT_SECOND ) { + Translate( &segPtr->u.c.center, segPtr->u.c.center, segPtr->u.c.a0+segPtr->u.c.a1, segPtr->u.c.radius-drawData.radius ); + } else { + Translate( &segPtr->u.c.center, segPtr->u.c.center, (segPtr->u.c.a0+segPtr->u.c.a1)/2.0, segPtr->u.c.radius-drawData.radius ); + } + drawDesc[CE].mode |= DESC_CHANGE; segPtr->u.c.radius = drawData.radius; + drawDesc[LN].mode |= DESC_CHANGE; break; case A1: - segPtr->u.c.a0 = NormalizeAngle( drawData.angle0-xx->angle ); - drawData.angle1 = NormalizeAngle( drawData.angle0+drawData.angle ); - drawDesc[A2].mode |= DESC_CHANGE; + switch ( drawData.pivot ) { + case DESC_PIVOT_FIRST: + segPtr->u.c.a1 = drawData.angle; + drawData.angle1 = NormalizeAngle( drawData.angle0+segPtr->u.c.a1 ); + drawDesc[A2].mode |= DESC_CHANGE; + break; + case DESC_PIVOT_SECOND: + segPtr->u.c.a0 = NormalizeAngle( segPtr->u.c.a1+segPtr->u.c.a0-drawData.angle); + segPtr->u.c.a1 = drawData.angle; + drawData.angle0 = NormalizeAngle( segPtr->u.c.a0+xx->angle ); + drawData.angle1 = NormalizeAngle( drawData.angle0+segPtr->u.c.a1 ); + drawDesc[A1].mode |= DESC_CHANGE; + drawDesc[A2].mode |= DESC_CHANGE; + break; + case DESC_PIVOT_MID: + segPtr->u.c.a0 = NormalizeAngle( segPtr->u.c.a0+segPtr->u.c.a1/2.0-drawData.angle/2.0); + segPtr->u.c.a1 = drawData.angle; + drawData.angle0 = NormalizeAngle( segPtr->u.c.a0+xx->angle ); + drawData.angle1 = NormalizeAngle( drawData.angle0+segPtr->u.c.a1 ); + drawDesc[A1].mode |= DESC_CHANGE; + drawDesc[A2].mode |= DESC_CHANGE; + break; + default: + break; + } break; case A2: segPtr->u.c.a0 = NormalizeAngle( drawData.angle1-segPtr->u.c.a1-xx->angle ); @@ -387,6 +947,28 @@ static void UpdateDraw( track_p trk, int inx, descData_p descUpd, BOOL_T final ) case TP: UNREORIGIN( segPtr->u.t.pos, drawData.endPt[0], xx->angle, xx->orig ); break; + case PP: + off.x = drawData.endPt[0].x - drawData.oldE0.x; + off.y = drawData.endPt[0].y - drawData.oldE0.y; + if (drawData.lock_origin) { + xx->orig.x +=off.x; + xx->orig.y +=off.y; + drawData.origin = xx->orig; + drawDesc[OI].mode |= DESC_CHANGE; + drawDesc[E0].mode |= DESC_CHANGE; + break; + } else { + for (int i=0;i<segPtr->u.p.cnt;i++) { + REORIGIN( pt, segPtr->u.p.pts[i].pt, xx->angle, xx->orig ); + pt.x += off.x; + pt.y += off.y; + if (i<5) drawData.endPt[i] = pt; + UNREORIGIN( segPtr->u.p.pts[i].pt, pt, 0.0, xx->orig ); + } + xx->angle = 0.0; + drawDesc[AL].mode |= DESC_CHANGE; + } + break; case TA: //segPtr->u.t.angle = NormalizeAngle( drawData.angle ); xx->angle = NormalizeAngle( drawData.angle ); @@ -396,6 +978,39 @@ static void UpdateDraw( track_p trk, int inx, descData_p descUpd, BOOL_T final ) UpdateFontSizeList( &fontSize, (wList_p)drawDesc[TS].control0, drawData.fontSizeInx ); segPtr->u.t.fontSize = fontSize; break; + case FL: + if (segPtr->type == SEG_POLY && drawData.open) { + drawData.filled = FALSE; + drawDesc[FL].mode |= DESC_CHANGE; + break; + } + if(drawData.filled) { + if (segPtr->type == SEG_POLY) segPtr->type = SEG_FILPOLY; + if (segPtr->type == SEG_CRVLIN) segPtr->type = SEG_FILCRCL; + } else { + if (segPtr->type == SEG_FILPOLY) segPtr->type = SEG_POLY; + if (segPtr->type == SEG_FILCRCL) { + segPtr->type = SEG_CRVLIN; + segPtr->u.c.a0 = 0.0; + segPtr->u.c.a1 = 360.0; + } + } + break; + case OP: + if (drawData.filled || (segPtr->type != SEG_POLY)) { + drawData.open = FALSE; + drawDesc[OP].mode |= DESC_CHANGE; + break; + } + if (drawData.open) { + if (segPtr->type == SEG_POLY && segPtr->u.p.polyType == FREEFORM) segPtr->u.p.polyType = POLYLINE; + } else { + if (segPtr->type == SEG_POLY && segPtr->u.p.polyType == POLYLINE) segPtr->u.p.polyType = FREEFORM; + } + break; + case BX: + segPtr->u.t.boxed = drawData.boxed; + break; case TX: if ( wTextGetModified((wText_p)drawDesc[TX].control0 )) { int len = wTextGetSize((wText_p)drawDesc[TX].control0); @@ -409,14 +1024,25 @@ static void UpdateDraw( track_p trk, int inx, descData_p descUpd, BOOL_T final ) case LY: SetTrkLayer( trk, drawData.layer); break; + case LK: + break; + case LT: + xx->lineType = drawData.lineType; + break; default: AbortProg( "bad op" ); } + drawData.oldE0 = drawData.endPt[0]; + drawData.oldE1 = drawData.endPt[1]; + drawData.oldAngle = drawData.angle; + drawData.oldOrigin = drawData.origin; ComputeDrawBoundingBox( trk ); DrawNewTrack( trk ); - DoCurCommand( C_REDRAW, zero ); + TempRedraw(); // UpdateDraw } +extern BOOL_T inDescribeCmd; + static void DescribeDraw( track_p trk, char * str, CSIZE_T len ) { struct extraData *xx = GetTrkExtraData(trk); @@ -443,8 +1069,17 @@ static void DescribeDraw( track_p trk, char * str, CSIZE_T len ) drawDesc[LY].mode = DESC_NOREDRAW; drawDesc[BE].mode = drawDesc[OR].mode = + drawDesc[LT].mode = drawDesc[DS].mode = DESC_IGNORE; drawData.pivot = DESC_PIVOT_MID; + + if ((xx->orig.x == 0.0) && (xx->orig.y == 0.0)) drawData.lock_origin = FALSE; + else drawData.lock_origin = TRUE; + + drawData.rotate_angle = xx->angle; + + drawDesc[LK].mode = 0; + switch ( segPtr->type ) { case SEG_STRLIN: case SEG_DIMLIN: @@ -454,24 +1089,35 @@ static void DescribeDraw( track_p trk, char * str, CSIZE_T len ) REORIGIN( drawData.endPt[1], segPtr->u.l.pos[1], xx->angle, xx->orig ); drawData.length = FindDistance( drawData.endPt[0], drawData.endPt[1] ); drawData.angle = FindAngle( drawData.endPt[0], drawData.endPt[1] ); + drawData.origin = xx->orig; drawDesc[LN].mode = drawDesc[AL].mode = drawDesc[PV].mode = 0; drawDesc[E0].mode = + drawDesc[OI].mode = 0; drawDesc[E1].mode = 0; + drawDesc[RA].mode = 0; switch (segPtr->type) { case SEG_STRLIN: title = _("Straight Line"); + drawDesc[LT].mode = 0; + drawData.lineType = (wIndex_t)xx->lineType; break; case SEG_DIMLIN: title = _("Dimension Line"); - drawDesc[CO].mode = DESC_IGNORE; - drawDesc[LW].mode = DESC_IGNORE; + drawDesc[CO].mode = + drawDesc[LW].mode = + drawDesc[LK].mode = + drawDesc[OI].mode = + drawDesc[RA].mode = DESC_IGNORE; drawData.dimenSize = (wIndex_t)segPtr->u.l.option; drawDesc[DS].mode = 0; break; case SEG_BENCH: title = _("Lumber"); + drawDesc[LK].mode = + drawDesc[OI].mode = + drawDesc[RA].mode = drawDesc[LW].mode = DESC_IGNORE; drawDesc[BE].mode = drawDesc[OR].mode = 0; @@ -480,6 +1126,9 @@ static void DescribeDraw( track_p trk, char * str, CSIZE_T len ) break; case SEG_TBLEDGE: title = _("Table Edge"); + drawDesc[LK].mode = + drawDesc[OI].mode = + drawDesc[RA].mode = DESC_IGNORE; drawDesc[CO].mode = DESC_IGNORE; drawDesc[LW].mode = DESC_IGNORE; break; @@ -488,10 +1137,17 @@ static void DescribeDraw( track_p trk, char * str, CSIZE_T len ) case SEG_CRVLIN: REORIGIN( drawData.center, segPtr->u.c.center, xx->angle, xx->orig ); drawData.radius = fabs(segPtr->u.c.radius); + drawData.origin = xx->orig; + drawDesc[OI].mode = 0; + drawDesc[RA].mode = drawDesc[CE].mode = - drawDesc[RA].mode = 0; + drawDesc[RD].mode = 0; + drawDesc[LT].mode = 0; + drawData.lineType = (wIndex_t)xx->lineType; if ( segPtr->u.c.a1 >= 360.0 ) { title = _("Circle"); + drawDesc[FL].mode = 0; + drawData.filled = FALSE; } else { drawData.angle = segPtr->u.c.a1; drawData.angle0 = NormalizeAngle( segPtr->u.c.a0+xx->angle ); @@ -499,64 +1155,127 @@ static void DescribeDraw( track_p trk, char * str, CSIZE_T len ) drawDesc[AL].mode = drawDesc[A1].mode = drawDesc[A2].mode = 0; + drawDesc[PV].mode = 0; title = _("Curved Line"); } break; case SEG_FILCRCL: REORIGIN( drawData.center, segPtr->u.c.center, xx->angle, xx->orig ); drawData.radius = fabs(segPtr->u.c.radius); + drawData.origin = xx->orig; + drawDesc[OI].mode = + drawDesc[RA].mode = + drawDesc[FL].mode = 0; + drawData.filled = TRUE; drawDesc[CE].mode = - drawDesc[RA].mode = 0; + drawDesc[RD].mode = 0; + drawDesc[PV].mode = 0; + drawDesc[OI].mode = 0; drawDesc[LW].mode = DESC_IGNORE; title = _("Filled Circle"); break; case SEG_POLY: + REORIGIN(drawData.endPt[0],segPtr->u.p.pts[0].pt, xx->angle, xx->orig); + drawDesc[PP].mode = 0; drawData.pointCount = segPtr->u.p.cnt; drawDesc[VC].mode = DESC_RO; - drawDesc[PT].mode = DESC_RO; + drawData.filled = FALSE; + drawDesc[FL].mode = 0; + drawData.angle = 0.0; + drawDesc[RA].mode = 0; + drawData.origin = xx->orig; + drawDesc[OI].mode = 0; + drawData.open=FALSE; + drawDesc[OP].mode = 0; + drawDesc[LT].mode = 0; + drawData.lineType = (wIndex_t)xx->lineType; switch (segPtr->u.p.polyType) { case RECTANGLE: - polyType = _("Rectangle"); + title = _("Rectangle"); + drawDesc[OP].mode = DESC_IGNORE; + drawDesc[VC].mode = DESC_IGNORE; + drawData.width = FindDistance(segPtr->u.p.pts[0].pt, segPtr->u.p.pts[1].pt); + drawDesc[WT].mode = 0; + drawData.height = FindDistance(segPtr->u.p.pts[0].pt, segPtr->u.p.pts[3].pt); + drawDesc[HT].mode = 0; + for(int i=0;i<4;i++) { + REORIGIN( drawData.endPt[i], segPtr->u.p.pts[i].pt, xx->angle, xx->orig ); + } + drawDesc[E0].mode = DESC_IGNORE; + drawData.origin = xx->orig; + break; + case POLYLINE: + title = _("Polyline"); + drawData.open=TRUE; break; default: - polyType = _("Freeform"); + title = _("Polygon"); } - strncpy( drawData.polyType, polyType, sizeof drawData.polyType ); - title = _("Polygonal Line"); break; case SEG_FILPOLY: + REORIGIN(drawData.endPt[0],segPtr->u.p.pts[0].pt, xx->angle, xx->orig); + drawDesc[PP].mode = 0; drawData.pointCount = segPtr->u.p.cnt; drawDesc[VC].mode = DESC_RO; + drawData.filled = TRUE; + drawDesc[FL].mode = 0; drawDesc[LW].mode = DESC_IGNORE; - drawDesc[PT].mode = DESC_RO; + drawData.angle = xx->angle; + drawDesc[RA].mode = 0; + drawData.origin = xx->orig; + drawDesc[OI].mode = DESC_RO; + drawData.open = FALSE; switch (segPtr->u.p.polyType) { case RECTANGLE: - polyType =_("Rectangle"); + title =_("Filled Rectangle"); + drawDesc[VC].mode = DESC_IGNORE; + drawData.width = FindDistance(segPtr->u.p.pts[0].pt, segPtr->u.p.pts[1].pt); + drawDesc[WT].mode = 0; + drawData.height = FindDistance(segPtr->u.p.pts[0].pt, segPtr->u.p.pts[3].pt); + drawDesc[HT].mode = 0; + for(int i=0;i<4;i++) { + REORIGIN( drawData.endPt[i], segPtr->u.p.pts[i].pt, xx->angle, xx->orig ); + } + drawDesc[E0].mode = DESC_IGNORE; + drawData.origin = xx->orig; break; default: - polyType = _("Freeform"); + title = _("Filled Polygon"); } - strncpy( drawData.polyType, polyType, sizeof drawData.polyType ); - title = _("Polygon"); break; case SEG_TEXT: REORIGIN( drawData.endPt[0], segPtr->u.t.pos, xx->angle, xx->orig ); drawData.angle = NormalizeAngle( xx->angle ); strncpy( drawData.text, segPtr->u.t.string, sizeof drawData.text ); drawData.text[sizeof drawData.text-1] ='\0'; + drawData.boxed = segPtr->u.t.boxed; + drawData.origin = xx->orig; + drawDesc[E0].mode = drawDesc[TP].mode = drawDesc[TS].mode = drawDesc[TX].mode = - drawDesc[TA].mode = + drawDesc[TA].mode = + drawDesc[BX].mode = + drawDesc[RA].mode = + drawDesc[OI].mode = 0; drawDesc[CO].mode = 0; /*Allow Text color setting*/ drawDesc[LW].mode = DESC_IGNORE; title = _("Text"); break; default: - AbortProg( "bad seg type" ); + ; } - sprintf( str, _("%s: Layer=%d"), title, GetTrkLayer(trk)+1 ); + snprintf( str, len, _("%s(%d) Layer=%d"), title, GetTrkIndex(trk), GetTrkLayer(trk)+1 ); + + if (!inDescribeCmd) return; + + drawData.oldE0 = drawData.endPt[0]; + drawData.oldE1 = drawData.endPt[1]; + drawData.oldAngle = drawData.angle; + drawData.oldOrigin = drawData.origin; + + DoDescribe( title, trk, drawDesc, UpdateDraw ); if ( segPtr->type==SEG_BENCH && drawDesc[BE].control0!=NULL && drawDesc[OR].control0!=NULL) { @@ -565,6 +1284,17 @@ static void DescribeDraw( track_p trk, char * str, CSIZE_T len ) BenchUpdateOrientationList( (long)wListGetItemContext((wList_p)drawDesc[BE].control0, drawData.benchChoice ), (wList_p)drawDesc[OR].control0 ); wListSetIndex( (wList_p)drawDesc[OR].control0, drawData.benchOrient ); } + if ( (segPtr->type==SEG_STRLIN || segPtr->type==SEG_CRVLIN || segPtr->type==SEG_POLY) && drawDesc[LT].control0!=NULL) { + wListClear( (wList_p)drawDesc[LT].control0 ); + wListAddValue( (wList_p)drawDesc[LT].control0, _("Solid"), NULL, (void*)0 ); + wListAddValue( (wList_p)drawDesc[LT].control0, _("Dash"), NULL, (void*)1 ); + wListAddValue( (wList_p)drawDesc[LT].control0, _("Dot"), NULL, (void*)2 ); + wListAddValue( (wList_p)drawDesc[LT].control0, _("DashDot"), NULL, (void*)3 ); + wListAddValue( (wList_p)drawDesc[LT].control0, _("DashDotDot"), NULL, (void*)4 ); + wListAddValue( (wList_p)drawDesc[LT].control0, _("CenterDot"), NULL, (void*)5 ); + wListAddValue( (wList_p)drawDesc[LT].control0, _("PhantomDot"), NULL, (void*)6 ); + wListSetIndex( (wList_p)drawDesc[LT].control0, drawData.lineType ); + } if ( segPtr->type==SEG_DIMLIN && drawDesc[DS].control0!=NULL ) { wListClear( (wList_p)drawDesc[DS].control0 ); wListAddValue( (wList_p)drawDesc[DS].control0, _("Tiny"), NULL, (void*)0 ); @@ -582,8 +1312,17 @@ static void DescribeDraw( track_p trk, char * str, CSIZE_T len ) static void DrawDraw( track_p t, drawCmd_p d, wDrawColor color ) { struct extraData * xx = GetTrkExtraData(t); - if ( (d->funcs->options&DC_QUICK) == 0 ) - DrawSegs( d, xx->orig, xx->angle, xx->segs, xx->segCnt, 0.0, color ); + unsigned long NotSolid = ~(DC_NOTSOLIDLINE); + d->options &= NotSolid; + if (xx->lineType == DRAWLINESOLID) {} + else if (xx->lineType == DRAWLINEDASH) d->options |= DC_DASH; + else if (xx->lineType == DRAWLINEDOT) d->options |= DC_DOT; + else if (xx->lineType == DRAWLINEDASHDOT) d->options |= DC_DASHDOT; + else if (xx->lineType == DRAWLINEDASHDOTDOT) d->options |= DC_DASHDOTDOT; + else if (xx->lineType == DRAWLINECENTER) d->options |= DC_CENTER; + else if (xx->lineType == DRAWLINEPHANTOM) d->options |= DC_PHANTOM; + DrawSegs( d, xx->orig, xx->angle, xx->segs, xx->segCnt, 0.0, color ); + d->options = d->options&~(DC_NOTSOLIDLINE); } @@ -594,6 +1333,7 @@ static void DeleteDraw( track_p t ) if (xx->segs[0].type == SEG_POLY || xx->segs[0].type == SEG_FILPOLY) { MyFree(xx->segs[0].u.p.pts); + xx->segs[0].u.p.pts = NULL; } } @@ -602,14 +1342,15 @@ static BOOL_T WriteDraw( track_p t, FILE * f ) { struct extraData * xx = GetTrkExtraData(t); BOOL_T rc = TRUE; - rc &= fprintf(f, "DRAW %d %d 0 0 0 %0.6f %0.6f 0 %0.6f\n", GetTrkIndex(t), GetTrkLayer(t), + rc &= fprintf(f, "DRAW %d %d %d 0 0 %0.6f %0.6f 0 %0.6f\n", GetTrkIndex(t), GetTrkLayer(t), + xx->lineType, xx->orig.x, xx->orig.y, xx->angle )>0; rc &= WriteSegs( f, xx->segCnt, xx->segs ); return rc; } -static void ReadDraw( char * header ) +static BOOL_T ReadDraw( char * header ) { track_p trk; wIndex_t index; @@ -617,12 +1358,14 @@ static void ReadDraw( char * header ) DIST_T elev; ANGLE_T angle; wIndex_t layer; + int lineType; struct extraData * xx; - if ( !GetArgs( header+5, paramVersion<3?"dXpYf":paramVersion<9?"dL000pYf":"dL000pff", - &index, &layer, &orig, &elev, &angle ) ) - return; - ReadSegs(); + if ( !GetArgs( header+5, paramVersion<3?"dXXpYf":paramVersion<9?"dLX00pYf":"dLd00pff", + &index, &layer, &lineType, &orig, &elev, &angle ) ) + return FALSE; + if ( !ReadSegs() ) + return FALSE; if (tempSegs_da.cnt == 1) { trk = MakeDrawFromSeg1( index, orig, angle, &tempSegs(0) ); SetTrkLayer( trk, layer ); @@ -633,9 +1376,11 @@ static void ReadDraw( char * header ) xx->orig = orig; xx->angle = angle; xx->segCnt = tempSegs_da.cnt; + xx->lineType = lineType; memcpy( xx->segs, tempSegs_da.ptr, tempSegs_da.cnt * sizeof *(trkSeg_p)0 ); ComputeDrawBoundingBox( trk ); } + return TRUE; } @@ -665,22 +1410,283 @@ static void RescaleDraw( track_p trk, FLOAT_T ratio ) RescaleSegs( xx->segCnt, xx->segs, ratio, ratio, ratio ); } +static void DoConvertFill(void) { + +} + +static drawModContext_t drawModCmdContext = { + InfoMessage, + DoRedraw, + &mainD}; + + +static BOOL_T infoSubst = FALSE; + +static paramIntegerRange_t i0_100 = { 0, 100, 25 }; +static paramFloatRange_t r1_10000 = { 1, 10000 }; +static paramFloatRange_t r0_10000 = { 0, 10000 }; +static paramFloatRange_t r10000_10000 = {-10000, 10000}; +static paramFloatRange_t r360_360 = { -360, 360, 80 }; +static paramFloatRange_t r0_360 = { 0, 360, 80 }; +static paramData_t drawModPLs[] = { + +#define drawModLengthPD (drawModPLs[0]) + { PD_FLOAT, &drawModCmdContext.length, "Length", PDO_DIM|PDO_NORECORD|BO_ENTER, &r0_10000, N_("Length") }, +#define drawModAnglePD (drawModPLs[1]) + { PD_FLOAT, &drawModCmdContext.abs_angle, "Angle", PDO_NORECORD|BO_ENTER, &r360_360, N_("Angle") }, +#define drawModRelAnglePD (drawModPLs[2]) +#define drawModRelAngle 2 + { PD_FLOAT, &drawModCmdContext.rel_angle, "Rel Angle", PDO_NORECORD|BO_ENTER, &r360_360, N_("Relative Angle") }, +#define drawModWidthPD (drawModPLs[3]) + { PD_FLOAT, &drawModCmdContext.width, "Width", PDO_DIM|PDO_NORECORD|BO_ENTER, &r0_10000, N_("Width") }, +#define drawModHeightPD (drawModPLs[4]) + { PD_FLOAT, &drawModCmdContext.height, "Height", PDO_DIM|PDO_NORECORD|BO_ENTER, &r0_10000, N_("Height") }, +#define drawModRadiusPD (drawModPLs[5]) +#define drawModRadius 5 + { PD_FLOAT, &drawModCmdContext.radius, "Radius", PDO_DIM|PDO_NORECORD|BO_ENTER, &r10000_10000, N_("Radius") }, +#define drawModArcAnglePD (drawModPLs[6]) + { PD_FLOAT, &drawModCmdContext.arc_angle, "ArcAngle", PDO_NORECORD|BO_ENTER, &r360_360, N_("Arc Angle") }, +#define drawModRotAnglePD (drawModPLs[7) + { PD_FLOAT, &drawModCmdContext.rot_angle, "Rot Angle", PDO_NORECORD|BO_ENTER, &r0_360, N_("Rotate Angle") }, +#define drawModRotCenterXPD (drawModPLs[8]) +#define drawModRotCenterInx 8 + { PD_FLOAT, &drawModCmdContext.rot_center.x, "Rot Center X,Y", PDO_NORECORD|BO_ENTER, &r0_10000, N_("Rot Center X") }, +#define drawModRotCenterYPD (drawModPLs[9]) + { PD_FLOAT, &drawModCmdContext.rot_center.y, " ", PDO_NORECORD|BO_ENTER, &r0_10000, N_("Rot Center Y") }, + +}; +static paramGroup_t drawModPG = { "drawMod", 0, drawModPLs, sizeof drawModPLs/sizeof drawModPLs[0] }; + +static void DrawModDlgUpdate( + paramGroup_p pg, + int inx, + void * valueP ) +{ + DrawGeomModify(C_UPDATE,zero,&drawModCmdContext); + ParamLoadControl(&drawModPG,drawModRotCenterInx-1); //Make sure the angle is updated in case center moved + ParamLoadControl(&drawModPG,drawModRadius); // Make sure Radius updated + ParamLoadControl(&drawModPG,drawModRelAngle); //Relative Angle as well + MainRedraw(); + +} static STATUS_T ModifyDraw( track_p trk, wAction_t action, coOrd pos ) { struct extraData * xx = GetTrkExtraData(trk); - STATUS_T rc; + STATUS_T rc = C_CONTINUE; - if (action == C_DOWN) { - //UndrawNewTrack( trk ); - } - if ( action == C_MOVE ) + wControl_p controls[5]; //Always needs a NULL last entry + char * labels[4]; + + drawModCmdContext.trk = trk; + drawModCmdContext.orig = xx->orig; + drawModCmdContext.angle = xx->angle; + drawModCmdContext.segCnt = xx->segCnt; + drawModCmdContext.segPtr = xx->segs; + drawModCmdContext.selected = GetTrkSelected(trk); + + + switch(action&0xFF) { //Remove Text value + case C_START: + drawModCmdContext.type = xx->segs[0].type; + switch(drawModCmdContext.type) { + case SEG_POLY: + case SEG_FILPOLY: + drawModCmdContext.filled = (drawModCmdContext.type==SEG_FILPOLY)?TRUE:FALSE; + drawModCmdContext.subtype = xx->segs[0].u.p.polyType; + drawModCmdContext.open = (drawModCmdContext.subtype==POLYLINE)?TRUE:FALSE; + break; + case SEG_TEXT: + InfoMessage("Text can only be modified in Describe Mode"); + wBeep(); + return C_ERROR; + default: + break; + + } + drawModCmdContext.rot_moved = FALSE; + drawModCmdContext.rotate_state = FALSE; + + infoSubst = FALSE; + rc = DrawGeomModify( C_START, pos, &drawModCmdContext ); + break; + case C_DOWN: + rc = DrawGeomModify( C_DOWN, pos, &drawModCmdContext ); + if ( infoSubst ) { + InfoSubstituteControls( NULL, NULL ); + infoSubst = FALSE; + } + break; + case C_LDOUBLE: + rc = DrawGeomModify( C_LDOUBLE, pos, &drawModCmdContext ); + if ( infoSubst ) { + InfoSubstituteControls( NULL, NULL ); + infoSubst = FALSE; + } + break; + case wActionMove: + rc = DrawGeomModify( action, pos, &drawModCmdContext ); + break; + case C_REDRAW: + rc = DrawGeomModify( action, pos, &drawModCmdContext ); + break; + case C_MOVE: + ignoredDraw = trk; + rc = DrawGeomModify( action, pos, &drawModCmdContext ); + ignoredDraw = NULL; + break; + case C_UP: + ignoredDraw = trk; + rc = DrawGeomModify( action, pos, &drawModCmdContext ); + ignoredDraw = NULL; + ComputeDrawBoundingBox( trk ); + if (drawModCmdContext.state == MOD_AFTER_PT) { + switch(drawModCmdContext.type) { + case SEG_POLY: + case SEG_FILPOLY: + if (xx->segs[0].u.p.polyType != RECTANGLE) { + if (drawModCmdContext.prev_inx >= 0) { + controls[0] = drawModLengthPD.control; + controls[1] = drawModRelAnglePD.control; + controls[2] = NULL; + labels[0] = N_("Seg Lth"); + labels[1] = N_("Rel Ang"); + ParamLoadControls( &drawModPG ); + InfoSubstituteControls( controls, labels ); + drawModLengthPD.option &= ~PDO_NORECORD; + drawModRelAnglePD.option &= ~PDO_NORECORD; + infoSubst = TRUE; + } + } else { + controls[0] = drawModWidthPD.control; + controls[1] = drawModHeightPD.control; + controls[2] = NULL; + labels[0] = N_("Width"); + labels[1] = N_("Height"); + ParamLoadControls( &drawModPG ); + InfoSubstituteControls( controls, labels ); + drawModWidthPD.option &= ~PDO_NORECORD; + drawModHeightPD.option &= ~PDO_NORECORD; + infoSubst = TRUE; + } + break; + case SEG_STRLIN: + case SEG_BENCH: + case SEG_DIMLIN: + case SEG_TBLEDGE: + controls[0] = drawModLengthPD.control; + controls[1] = drawModAnglePD.control; + controls[2] = NULL; + labels[0] = N_("Length"); + labels[1] = N_("Angle"); + ParamLoadControls( &drawModPG ); + InfoSubstituteControls( controls, labels ); + drawModLengthPD.option &= ~PDO_NORECORD; + drawModAnglePD.option &= ~PDO_NORECORD; + infoSubst = TRUE; + break; + case SEG_CRVLIN: + case SEG_FILCRCL: + controls[0] = drawModRadiusPD.control; + controls[1] = NULL; + labels[0] = N_("Radius"); + if ((drawModCmdContext.type == SEG_CRVLIN) && xx->segs[0].u.c.a1>0.0 && xx->segs[0].u.c.a1 <360.0) { + controls[1] = drawModArcAnglePD.control; + controls[2] = NULL; + labels[1] = N_("Arc Angle"); + } + ParamLoadControls( &drawModPG ); + InfoSubstituteControls( controls, labels ); + drawModArcAnglePD.option &= ~PDO_NORECORD; + if (drawModCmdContext.type == SEG_CRVLIN) + drawModArcAnglePD.option &= ~PDO_NORECORD; + infoSubst = TRUE; + break; + default: + InfoSubstituteControls( NULL, NULL ); + infoSubst = FALSE; + break; + } + } else { + InfoSubstituteControls( NULL, NULL ); + infoSubst = FALSE; + } + break; + case C_CMDMENU: + menuPos = pos; + wMenuPopupShow( drawModDelMI ); + wMenuPushEnable( drawModPointsMode,drawModCmdContext.rotate_state); + wMenuPushEnable( drawModriginMode,!drawModCmdContext.rotate_state); + wMenuPushEnable( drawModRound, FALSE); + wMenuPushEnable( drawModVertex, FALSE); + wMenuPushEnable( drawModSmooth, FALSE); + wMenuPushEnable( drawModDel, FALSE); + wMenuPushEnable( drawModFill, FALSE); + wMenuPushEnable( drawModEmpty, FALSE); + wMenuPushEnable( drawModClose, FALSE); + wMenuPushEnable( drawModOpen, FALSE); + wMenuPushEnable( drawModSolid, TRUE); + wMenuPushEnable( drawModDot, TRUE); + wMenuPushEnable( drawModDash, TRUE); + wMenuPushEnable( drawModDashDot, TRUE); + wMenuPushEnable( drawModDashDotDot, TRUE); + wMenuPushEnable( drawModCenterDot, TRUE); + wMenuPushEnable( drawModPhantom, TRUE); + if (!drawModCmdContext.rotate_state && (drawModCmdContext.type == SEG_POLY || drawModCmdContext.type == SEG_FILPOLY)) { + wMenuPushEnable( drawModDel,drawModCmdContext.prev_inx>=0); + if ((!drawModCmdContext.open && drawModCmdContext.prev_inx>=0) || + ((drawModCmdContext.prev_inx>0) && (drawModCmdContext.prev_inx<drawModCmdContext.max_inx))) { + wMenuPushEnable( drawModRound,TRUE); + wMenuPushEnable( drawModVertex, TRUE); + wMenuPushEnable( drawModSmooth, TRUE); + } + wMenuPushEnable( drawModFill, (!drawModCmdContext.open) && (!drawModCmdContext.filled)); + wMenuPushEnable( drawModEmpty, (!drawModCmdContext.open) && (drawModCmdContext.filled)); + wMenuPushEnable( drawModClose, drawModCmdContext.open); + wMenuPushEnable( drawModOpen, !drawModCmdContext.open); + } + wMenuPushEnable( drawModOrigin,drawModCmdContext.rotate_state); + wMenuPushEnable( drawModLast,drawModCmdContext.rotate_state && (drawModCmdContext.prev_inx>=0)); + wMenuPushEnable( drawModCenter,drawModCmdContext.rotate_state); + break; + case C_TEXT: + ignoredDraw = trk ; + rc = DrawGeomModify( action, pos, &drawModCmdContext ); + if ( infoSubst ) { + InfoSubstituteControls( NULL, NULL ); + infoSubst = FALSE; + } + ignoredDraw = NULL; + if (rc == C_CONTINUE) break; + /* no break*/ + case C_FINISH: ignoredDraw = trk; - rc = DrawGeomModify( xx->orig, xx->angle, xx->segCnt, xx->segs, action, pos, GetTrkSelected(trk) ); - ignoredDraw = NULL; - if (action == C_UP) { + rc = DrawGeomModify( C_FINISH, pos, &drawModCmdContext ); + xx->angle = drawModCmdContext.angle; + xx->orig = drawModCmdContext.orig; + ignoredDraw = NULL; ComputeDrawBoundingBox( trk ); - DrawNewTrack( trk ); + DYNARR_RESET(trkSeg_t,tempSegs_da); + if ( infoSubst ) { + InfoSubstituteControls( NULL, NULL ); + infoSubst = FALSE; + } + break; + case C_CANCEL: + case C_CONFIRM: + case C_TERMINATE: + rc = DrawGeomModify( action, pos, &drawModCmdContext ); + drawModCmdContext.state = MOD_NONE; + DYNARR_RESET(trkSeg_t,tempSegs_da); + if ( infoSubst ) { + InfoSubstituteControls( NULL, NULL ); + infoSubst = FALSE; + } + break; + + default: + + break; } return rc; } @@ -768,7 +1774,7 @@ static BOOL_T StoreDraw( if (xx->segs[0].type == SEG_POLY || xx->segs[0].type == SEG_FILPOLY) { *data = xx->segs[0].u.p.pts; - *len = xx->segs[0].u.p.cnt* sizeof (coOrd); + *len = xx->segs[0].u.p.cnt* sizeof (pts_t); return TRUE; } return FALSE; @@ -789,6 +1795,275 @@ static BOOL_T ReplayDraw( return FALSE; } +static BOOL_T QueryDraw( track_p trk, int query ) +{ + struct extraData * xx = GetTrkExtraData(trk); + switch(query) { + case Q_IS_DRAW: + return TRUE; + case Q_IS_POLY: + if ((xx->segs[0].type == SEG_POLY) || (xx->segs[0].type == SEG_FILPOLY) ) { + return TRUE; + } + else + return FALSE; + case Q_IS_TEXT: + if (xx->segs[0].type== SEG_TEXT) return TRUE; + else return FALSE; + case Q_GET_NODES: + return TRUE; + case Q_CAN_PARALLEL: + if ((xx->segs[0].type == SEG_STRLIN) || (xx->segs[0].type == SEG_CRVLIN || + ((xx->segs[0].type == SEG_POLY) && (xx->segs[0].u.p.polyType == POLYLINE)) + )) return TRUE; + else return FALSE; + default: + return FALSE; + } +} + +static wBool_t CompareDraw( track_cp trk1, track_cp trk2 ) +{ + struct extraData *xx1 = GetTrkExtraData( trk1 ); + struct extraData *xx2 = GetTrkExtraData( trk2 ); + char * cp = message + strlen(message); + REGRESS_CHECK_POS( "Orig", xx1, xx2, orig ) + REGRESS_CHECK_ANGLE( "Angle", xx1, xx2, angle ) + REGRESS_CHECK_INT( "LineType", xx1, xx2, lineType ) + return CompareSegs( xx1->segs, xx1->segCnt, xx2->segs, xx2->segCnt ); +} + +static BOOL_T GetParamsDraw( int inx, track_p trk, coOrd pos, trackParams_t * params ) { + + struct extraData * xx = GetTrkExtraData(trk); + if (inx != PARAMS_NODES ) return FALSE; + DYNARR_RESET(coOrd,params->nodes); + BOOL_T back = FALSE; + coOrd start,end; + switch (xx->segs[0].type) { + case SEG_POLY: + if (xx->segs[0].u.p.polyType != POLYLINE) return FALSE; + REORIGIN(start,xx->segs[0].u.p.pts[0].pt,xx->angle,xx->orig); + REORIGIN(end,xx->segs[0].u.p.pts[xx->segs[0].u.p.cnt-1].pt,xx->angle,xx->orig); + if (FindDistance(pos,start)>FindDistance(pos,end)) back = TRUE; + for (int i=0;i<xx->segs[0].u.p.cnt;i++) { + DYNARR_APPEND(coOrd,params->nodes,xx->segs[0].u.p.cnt); + if (back) + DYNARR_LAST(coOrd,params->nodes) = xx->segs[0].u.p.pts[xx->segs[0].u.p.cnt-1-i].pt; + else + DYNARR_LAST(coOrd,params->nodes) = xx->segs[0].u.p.pts[i].pt; + REORIGIN(DYNARR_LAST(coOrd,params->nodes),DYNARR_LAST(coOrd,params->nodes),xx->angle,xx->orig); + } + params->lineOrig = DYNARR_N(coOrd,params->nodes,0); + params->lineEnd = DYNARR_LAST(coOrd,params->nodes); + return TRUE; + + case SEG_STRLIN:; + REORIGIN(start,xx->segs[0].u.l.pos[0],xx->angle,xx->orig); + REORIGIN(end,xx->segs[0].u.l.pos[1],xx->angle,xx->orig); + if (FindDistance(pos,start)>FindDistance(pos,end)) back = TRUE; + for (int i=0;i<2;i++) { + DYNARR_APPEND(coOrd,params->nodes,2); + REORIGIN(DYNARR_LAST(coOrd,params->nodes),xx->segs[0].u.l.pos[back?1-i:i],xx->angle,xx->orig); + } + params->lineOrig = DYNARR_N(coOrd,params->nodes,0); + params->lineEnd = DYNARR_LAST(coOrd,params->nodes); + return TRUE; + + case SEG_CRVLIN:; + Translate(&start,xx->segs[0].u.c.center,xx->segs[0].u.c.a0,fabs(xx->segs[0].u.c.radius)); + REORIGIN(start,start,xx->angle,xx->orig); + Translate(&end,xx->segs[0].u.c.center,xx->segs[0].u.c.a0+xx->segs[0].u.c.a1,fabs(xx->segs[0].u.c.radius)); + REORIGIN(end,end,xx->angle,xx->orig); + if (FindDistance(start,pos) > FindDistance(end,pos)) back = TRUE; + if (fabs(xx->segs[0].u.c.radius) > 0.5) { + double min_angle = R2D(2*acos(1.0-(0.1/fabs(xx->segs[0].u.c.radius)))); //Error max is 0.1" + int number = (int) ceil(xx->segs[0].u.c.a1/min_angle); + double arc_size = xx->segs[0].u.c.a1/number; + for (int i=0;i<=number;i++) { + DYNARR_APPEND(coOrd,params->nodes,number); + if (back) + Translate(&DYNARR_LAST(coOrd,params->nodes),xx->segs[0].u.c.center,xx->segs[0].u.c.a0+xx->segs[0].u.c.a1-(i*arc_size),fabs(xx->segs[0].u.c.radius)); + else + Translate(&DYNARR_LAST(coOrd,params->nodes),xx->segs[0].u.c.center,xx->segs[0].u.c.a0+(i*arc_size),fabs(xx->segs[0].u.c.radius)); + REORIGIN(DYNARR_LAST(coOrd,params->nodes),DYNARR_LAST(coOrd,params->nodes),xx->angle,xx->orig); + } + } else { + DYNARR_APPEND(coOrd,params->nodes,2); + REORIGIN(DYNARR_LAST(coOrd,params->nodes),back?end:start,xx->angle,xx->orig); + DYNARR_APPEND(coOrd,params->nodes,2); + REORIGIN(DYNARR_LAST(coOrd,params->nodes),back?start:end,xx->angle,xx->orig); + } + params->lineOrig = DYNARR_N(coOrd,params->nodes,0); + params->lineEnd = DYNARR_LAST(coOrd,params->nodes); + return TRUE; + + case SEG_BEZLIN: + REORIGIN(start,xx->segs[0].u.b.pos[0],xx->angle,xx->orig); + REORIGIN(end,xx->segs[0].u.b.pos[3],xx->angle,xx->orig); + if (FindDistance(pos,start) < FindDistance(pos,end)) + params->ep = 0; + else params->ep = 1; + BOOL_T back = FALSE; + coOrd curr_pos = params->bezierPoints[params->ep*3]; + BOOL_T first = TRUE; + for (int i = 0; i<xx->segs[0].bezSegs.cnt;i++) { + trkSeg_p segPtr = &DYNARR_N(trkSeg_t,xx->segs[0].bezSegs,params->ep?xx->segs[0].bezSegs.cnt-1-i:i); + if (segPtr->type == SEG_STRLIN) { + back = FindDistance(segPtr->u.l.pos[0],curr_pos)>FindDistance(segPtr->u.l.pos[1],curr_pos); + if (first) { + first = FALSE; + DYNARR_APPEND(coOrd,params->nodes,2); + REORIGIN(DYNARR_LAST(coOrd,params->nodes),segPtr->u.l.pos[back],xx->angle,xx->orig); + } + DYNARR_APPEND(coOrd,params->nodes,2); + REORIGIN(DYNARR_LAST(coOrd,params->nodes),segPtr->u.l.pos[1-back],xx->angle,xx->orig); + curr_pos = DYNARR_LAST(coOrd,params->nodes); + } else { + coOrd start,end; + Translate(&start,segPtr->u.c.center,segPtr->u.c.a0,segPtr->u.c.radius); + Translate(&end,segPtr->u.c.center,segPtr->u.c.a0+segPtr->u.c.a1,segPtr->u.c.radius); + back = FindDistance(start,curr_pos)>FindDistance(end,curr_pos); + if (fabs(segPtr->u.c.radius) > 0.2) { + double min_angle = 360*acos(1.0-(0.1/fabs(segPtr->u.c.radius)))/M_PI; //Error max is 0.1" + int number = (int)ceil(segPtr->u.c.a1/min_angle); + double arc_size = segPtr->u.c.a1/number; + for (int j=1-first;j<number;j++) { + DYNARR_APPEND(coOrd,params->nodes,number-first); + if (back == params->ep) + Translate(&DYNARR_LAST(coOrd,params->nodes),segPtr->u.c.center,segPtr->u.c.a0+(j*arc_size),fabs(segPtr->u.c.radius) ); + else + Translate(&DYNARR_LAST(coOrd,params->nodes),segPtr->u.c.center,segPtr->u.c.a0+segPtr->u.c.a1-(j*arc_size),fabs(segPtr->u.c.radius) ); + REORIGIN(DYNARR_LAST(coOrd,params->nodes),DYNARR_LAST(coOrd,params->nodes),xx->angle,xx->orig); + } + first = FALSE; + } else { + if (first) { + first = FALSE; + DYNARR_APPEND(coOrd,params->nodes,2); + REORIGIN(DYNARR_LAST(coOrd,params->nodes),start,xx->angle,xx->orig); + } + DYNARR_APPEND(coOrd,params->nodes,1); + REORIGIN(DYNARR_LAST(coOrd,params->nodes),end,xx->angle,xx->orig); + first = FALSE; + } + curr_pos = DYNARR_LAST(coOrd,params->nodes); + } + } + params->lineOrig = DYNARR_N(coOrd,params->nodes,0); + params->lineEnd = DYNARR_LAST(coOrd,params->nodes); + return TRUE; + + default: + return FALSE; + } + return FALSE; + + +} + +static BOOL_T MakeParallelDraw( + track_p trk, + coOrd pos, + DIST_T sep, + DIST_T factor, + track_p * newTrkR, + coOrd * p0R, + coOrd * p1R, + BOOL_T track) +{ + if (track) return FALSE; + struct extraData * xx = GetTrkExtraData(trk); + + ANGLE_T angle; + DIST_T rad; + coOrd p0,p1; + + switch (xx->segs[0].type) { + case SEG_STRLIN: + angle = FindAngle(xx->segs[0].u.l.pos[0],xx->segs[0].u.l.pos[1]); + if ( NormalizeAngle( FindAngle( xx->segs[0].u.l.pos[0], pos ) - angle ) < 180.0 ) + angle += 90; + else + angle -= 90; + Translate(&p0,xx->segs[0].u.l.pos[0], angle, sep); + Translate(&p1,xx->segs[0].u.l.pos[1], angle, sep); + tempSegs(0).color = xx->segs[0].color; + tempSegs(0).width = xx->segs[0].width; + tempSegs_da.cnt = 1; + tempSegs(0).type = SEG_STRLIN; + tempSegs(0).u.l.pos[0] = p0; + tempSegs(0).u.l.pos[1] = p1; + if (newTrkR) { + *newTrkR = MakeDrawFromSeg( zero, 0.0, &tempSegs(0) ); + struct extraData * yy = GetTrkExtraData(*newTrkR); + yy->lineType = xx->lineType; + } + + if ( p0R ) *p0R = p0; + if ( p1R ) *p1R = p1; + return TRUE; + break; + case SEG_CRVLIN: + rad = FindDistance( pos, xx->segs[0].u.c.center ); + if ( rad > xx->segs[0].u.c.radius ) + rad = xx->segs[0].u.c.radius + sep; + else + rad = xx->segs[0].u.c.radius - sep; + tempSegs(0).color = xx->segs[0].color; + tempSegs(0).width = xx->segs[0].width; + tempSegs_da.cnt = 1; + tempSegs(0).type = SEG_CRVLIN; + tempSegs(0).u.c.center = xx->segs[0].u.c.center; + tempSegs(0).u.c.radius = rad; + tempSegs(0).u.c.a0 = xx->segs[0].u.c.a0; + tempSegs(0).u.c.a1 = xx->segs[0].u.c.a1; + if (newTrkR) { + *newTrkR = MakeDrawFromSeg( zero, 0.0, &tempSegs(0) ); + struct extraData * yy = GetTrkExtraData(*newTrkR); + yy->lineType = xx->lineType; + } + if ( p0R ) PointOnCircle( p0R, xx->segs[0].u.c.center, rad, xx->segs[0].u.c.a0 ); + if ( p1R ) PointOnCircle( p1R, xx->segs[0].u.c.center, rad, xx->segs[0].u.c.a0+xx->segs[0].u.c.a1 ); + return TRUE; + break; + case SEG_POLY: + if (xx->segs[0].u.p.polyType != POLYLINE) return FALSE; + int inx2; + coOrd p = pos; + angle = GetAngleSegs(1,&xx->segs[0],&p,NULL,NULL,NULL,&inx2,NULL); + if ( NormalizeAngle( FindAngle( p, pos ) - angle ) < 180.0 ) { + sep = sep*1.0; + angle += 90; + } else { + angle -= 90; + sep = sep*1.0; + } + tempSegs(0).color = xx->segs[0].color; + tempSegs(0).width = xx->segs[0].width; + tempSegs_da.cnt = 1; + tempSegs(0).type = SEG_POLY; + tempSegs(0).u.p.polyType = POLYLINE; + tempSegs(0).u.p.pts = memdup( xx->segs[0].u.p.pts, xx->segs[0].u.p.cnt*sizeof (pts_t) ); + tempSegs(0).u.p.cnt = xx->segs[0].u.p.cnt; + for (int i=0;i<xx->segs[0].u.p.cnt;i++) { + Translate(&tempSegs(0).u.p.pts[i].pt,tempSegs(0).u.p.pts[i].pt,angle,sep); + } + if (newTrkR) { + *newTrkR = MakeDrawFromSeg( zero, 0.0, &tempSegs(0) ); + struct extraData * yy = GetTrkExtraData(*newTrkR); + yy->lineType = xx->lineType; + if (tempSegs(0).u.p.pts) MyFree(tempSegs(0).u.p.pts); + } + if (p0R) *p0R = tempSegs(0).u.p.pts[0].pt; + if (p1R) *p1R = tempSegs(0).u.p.pts[tempSegs(0).u.p.cnt-1].pt; + return TRUE; + break; + default: + return FALSE; + } + return FALSE; +} static trackCmd_t drawCmds = { "DRAW", @@ -811,19 +2086,21 @@ static trackCmd_t drawCmds = { NULL, /* merge */ ModifyDraw, NULL, /* getLength */ - NULL, /* getTrackParams */ + GetParamsDraw, /* getTrackParams */ NULL, /* moveEndPt */ - NULL, /* query */ + QueryDraw, /* query */ UngroupDraw, FlipDraw, NULL, NULL, NULL, - NULL, /*Parallel*/ + MakeParallelDraw, /*Parallel*/ NULL, NULL, /*MakeSegs*/ ReplayDraw, - StoreDraw + StoreDraw, + NULL, + CompareDraw }; EXPORT BOOL_T OnTableEdgeEndPt( track_p trk, coOrd * pos ) @@ -918,19 +2195,12 @@ EXPORT BOOL_T GetClosestEndPt( track_p trk, coOrd * pos) } -static void DrawRedraw(void); static drawContext_t drawCmdContext = { InfoMessage, - DrawRedraw, + DoRedraw, &mainD, OP_LINE }; -static void DrawRedraw( void ) -{ - MainRedraw(); - MapRedraw(); -} - static wIndex_t benchChoice; static wIndex_t benchOrient; static wIndex_t dimArrowSize; @@ -939,10 +2209,10 @@ long lineWidth = 0; static wDrawColor benchColor; -static paramIntegerRange_t i0_100 = { 0, 100, 25 }; + static paramData_t drawPLs[] = { -#define drawWidthPD (drawPLs[0]) - { PD_LONG, &drawCmdContext.Width, "linewidth", PDO_NORECORD, &i0_100, N_("Line Width") }, +#define drawLineWidthPD (drawPLs[0]) + { PD_LONG, &drawCmdContext.line_Width, "linewidth", PDO_NORECORD, &i0_100, N_("Line Width") }, #define drawColorPD (drawPLs[1]) { PD_COLORLIST, &lineColor, "linecolor", PDO_NORECORD, NULL, N_("Color") }, #define drawBenchColorPD (drawPLs[2]) @@ -960,7 +2230,19 @@ static paramData_t drawPLs[] = { { PD_DROPLIST, &benchOrient, "benchorient", PDO_NOPREF|PDO_NORECORD|PDO_LISTINDEX, (void*)105, "", 0 }, #endif #define drawDimArrowSizePD (drawPLs[5]) - { PD_DROPLIST, &dimArrowSize, "arrowsize", PDO_NORECORD|PDO_LISTINDEX, (void*)80, N_("Size") } }; + { PD_DROPLIST, &dimArrowSize, "arrowsize", PDO_NORECORD|PDO_LISTINDEX, (void*)80, N_("Size") }, +#define drawLengthPD (drawPLs[6]) + { PD_FLOAT, &drawCmdContext.length, "Length", PDO_DIM|PDO_NORECORD|BO_ENTER, &r0_10000, N_("Length") }, +#define drawWidthPD (drawPLs[7]) + { PD_FLOAT, &drawCmdContext.width, "BoxWidth", PDO_DIM|PDO_NORECORD|BO_ENTER, &r0_10000, N_("Width") }, +#define drawAnglePD (drawPLs[8]) +#define drawAngleInx 8 + { PD_FLOAT, &drawCmdContext.angle, "Angle", PDO_NORECORD|BO_ENTER, &r360_360, N_("Angle") }, +#define drawRadiusPD (drawPLs[9]) + { PD_FLOAT, &drawCmdContext.radius, "Radius", PDO_DIM|PDO_NORECORD|BO_ENTER, &r0_10000, N_("Radius") }, +#define drawLineTypePD (drawPLs[10]) + { PD_DROPLIST, &drawCmdContext.lineType, "Type", PDO_DIM|PDO_NORECORD|BO_ENTER, (void*)0, N_("Line Type") }, +}; static paramGroup_t drawPG = { "draw", 0, drawPLs, sizeof drawPLs/sizeof drawPLs[0] }; static char * objectName[] = { @@ -976,21 +2258,22 @@ static char * objectName[] = { N_("Circle"), N_("Circle"), N_("Box"), - N_("Polyline"), + N_("Polygon"), N_("Filled Circle"), N_("Filled Circle"), N_("Filled Circle"), N_("Filled Box"), - N_("Polygon"), + N_("Filled Polygon"), N_("Bezier Line"), + N_("Polyline"), NULL}; static STATUS_T CmdDraw( wAction_t action, coOrd pos ) { static BOOL_T infoSubst = FALSE; - wControl_p controls[4]; - char * labels[3]; + wControl_p controls[5]; //Always needs a NULL last entry + char * labels[4]; static char labelName[40]; wAction_t act2 = (action&0xFF) | (bezCmdCreateLine<<8); @@ -1000,7 +2283,7 @@ static STATUS_T CmdDraw( wAction_t action, coOrd pos ) case C_START: ParamLoadControls( &drawPG ); /*drawContext = &drawCmdContext;*/ - drawWidthPD.option |= PDO_NORECORD; + drawLineWidthPD.option |= PDO_NORECORD; drawColorPD.option |= PDO_NORECORD; drawBenchColorPD.option |= PDO_NORECORD; drawBenchChoicePD.option |= PDO_NORECORD; @@ -1021,19 +2304,29 @@ static STATUS_T CmdDraw( wAction_t action, coOrd pos ) case OP_CURVE4: case OP_CIRCLE2: case OP_CIRCLE3: + case OP_BEZLIN: case OP_BOX: case OP_POLY: - case OP_BEZLIN: - controls[0] = drawWidthPD.control; + case OP_POLYLINE: + controls[0] = drawLineWidthPD.control; controls[1] = drawColorPD.control; + controls[2] = drawLineTypePD.control; controls[2] = NULL; sprintf( labelName, _("%s Line Width"), _(objectName[drawCmdContext.Op]) ); labels[0] = labelName; labels[1] = N_("Color"); + labels[2] = N_("Type"); + if ( wListGetCount( (wList_p)drawLineTypePD.control ) == 0 ) { + wListAddValue( (wList_p)drawLineTypePD.control, _("Solid"), NULL, NULL ); + wListAddValue( (wList_p)drawLineTypePD.control, _("Dot"), NULL, NULL ); + wListAddValue( (wList_p)drawLineTypePD.control, _("Dash"), NULL, NULL ); + wListAddValue( (wList_p)drawLineTypePD.control, _("Dash-Dot"), NULL, NULL ); + wListAddValue( (wList_p)drawLineTypePD.control, _("Dash-Dot-Dot"), NULL, NULL ); + } InfoSubstituteControls( controls, labels ); - drawWidthPD.option &= ~PDO_NORECORD; + drawLineWidthPD.option &= ~PDO_NORECORD; drawColorPD.option &= ~PDO_NORECORD; - lineWidth = drawCmdContext.Width; + drawLineTypePD.option &= ~PDO_NORECORD; break; case OP_FILLCIRCLE2: case OP_FILLCIRCLE3: @@ -1065,6 +2358,7 @@ static STATUS_T CmdDraw( wAction_t action, coOrd pos ) drawBenchColorPD.option &= ~PDO_NORECORD; drawBenchChoicePD.option &= ~PDO_NORECORD; drawBenchOrientPD.option &= ~PDO_NORECORD; + drawLengthPD.option &= ~PDO_NORECORD; break; case OP_DIMLINE: controls[0] = drawDimArrowSizePD.control; @@ -1081,9 +2375,7 @@ static STATUS_T CmdDraw( wAction_t action, coOrd pos ) drawDimArrowSizePD.option &= ~PDO_NORECORD; break; case OP_TBLEDGE: - InfoSubstituteControls( NULL, NULL ); InfoMessage( _("Drag to create Table Edge") ); - drawColorPD.option &= ~PDO_NORECORD; break; default: InfoSubstituteControls( NULL, NULL ); @@ -1091,8 +2383,7 @@ static STATUS_T CmdDraw( wAction_t action, coOrd pos ) } ParamGroupRecord( &drawPG ); if (drawCmdContext.Op == OP_BEZLIN) return CmdBezCurve(act2, pos); - DrawGeomMouse( C_START, pos, &drawCmdContext ); - + DrawGeomMouse( C_START, pos, &drawCmdContext); return C_CONTINUE; case wActionLDown: @@ -1106,7 +2397,10 @@ static STATUS_T CmdDraw( wAction_t action, coOrd pos ) drawCmdContext.Color = benchColor; } else if ( drawCmdContext.Op == OP_DIMLINE ) { + drawCmdContext.Color = wDrawColorBlack; drawCmdContext.benchOption = dimArrowSize; + } else if ( drawCmdContext.Op == OP_TBLEDGE ) { + drawCmdContext.Color = wDrawColorBlack; } else { drawCmdContext.Color = lineColor; } @@ -1114,39 +2408,132 @@ static STATUS_T CmdDraw( wAction_t action, coOrd pos ) InfoSubstituteControls( NULL, NULL ); infoSubst = FALSE; } + /* no break */ case wActionLDrag: ParamLoadData( &drawPG ); + /* no break */ case wActionMove: - case wActionLUp: case wActionRDown: case wActionRDrag: - case wActionRUp: - case wActionText: - case C_CMDMENU: if (drawCmdContext.Op == OP_BEZLIN) return CmdBezCurve(act2, pos); - if (!((MyGetKeyState() & WKEY_SHIFT) != 0)) { + if (!((MyGetKeyState() & WKEY_ALT) != magneticSnap)) { SnapPos( &pos ); } - return DrawGeomMouse( action, pos, &drawCmdContext ); + return DrawGeomMouse( action, pos, &drawCmdContext); + case wActionLUp: + case wActionRUp: + if (drawCmdContext.Op == OP_BEZLIN) return CmdBezCurve(act2, pos); + //if (!((MyGetKeyState() & WKEY_SHIFT) != 0)) { + // SnapPos( &pos ); Remove Snap at end of action - it will have been imposed in Geom if needed + //} + int rc = DrawGeomMouse( action, pos, &drawCmdContext); + // Put up text entry boxes ready for updates if the result was continue + if (rc == C_CONTINUE) { + switch( drawCmdContext.Op ) { + case OP_CIRCLE1: + case OP_CIRCLE2: + case OP_CIRCLE3: + case OP_FILLCIRCLE1: + case OP_FILLCIRCLE2: + case OP_FILLCIRCLE3: + controls[0] = drawRadiusPD.control; + controls[1] = NULL; + labels[0] = N_("Radius"); + ParamLoadControls( &drawPG ); + InfoSubstituteControls( controls, labels ); + drawRadiusPD.option &= ~PDO_NORECORD; + infoSubst = TRUE; + break; + case OP_CURVE1: + case OP_CURVE2: + case OP_CURVE3: + case OP_CURVE4: + if (drawCmdContext.ArcData.type == curveTypeCurve) { + controls[0] = drawRadiusPD.control; + controls[1] = drawAnglePD.control; + controls[2] = NULL; + labels[0] = N_("Radius"); + labels[1] = N_("Arc Angle"); + } else { + controls[0] = drawLengthPD.control; + controls[1] = drawAnglePD.control; + controls[2] = NULL; + labels[0] = N_("Length"); + labels[1] = N_("Angle"); + } + ParamLoadControls( &drawPG ); + InfoSubstituteControls( controls, labels ); + drawLengthPD.option &= ~PDO_NORECORD; + drawRadiusPD.option &= ~PDO_NORECORD; + drawAnglePD.option &= ~PDO_NORECORD; + infoSubst = TRUE; + break; + case OP_LINE: + case OP_BENCH: + case OP_TBLEDGE: + case OP_POLY: + case OP_FILLPOLY: + case OP_POLYLINE: + controls[0] = drawLengthPD.control; + controls[1] = drawAnglePD.control; + controls[2] = NULL; + labels[0] = N_("Seg Length"); + if (drawCmdContext.Op == OP_LINE || drawCmdContext.Op == OP_BENCH || drawCmdContext.Op == OP_TBLEDGE) + labels[1] = N_("Angle"); + else if (drawCmdContext.index > 0 ) + labels[1] = N_("Rel Angle"); + else + labels[1] = N_("Angle"); + ParamLoadControls( &drawPG ); + InfoSubstituteControls( controls, labels ); + drawLengthPD.option &= ~PDO_NORECORD; + drawAnglePD.option &= ~PDO_NORECORD; + infoSubst = TRUE; + break; + case OP_BOX: + case OP_FILLBOX: + controls[0] = drawLengthPD.control; + controls[1] = drawWidthPD.control; + controls[2] = NULL; + labels[0] = N_("Length"); + labels[1] = N_("Width"); + ParamLoadControls( &drawPG ); + InfoSubstituteControls( controls, labels ); + drawLengthPD.option &= ~PDO_NORECORD; + drawWidthPD.option &= ~PDO_NORECORD; + infoSubst = TRUE; + break; + default: + break; + } + } + return rc; case C_CANCEL: InfoSubstituteControls( NULL, NULL ); if (drawCmdContext.Op == OP_BEZLIN) return CmdBezCurve(act2, pos); - return DrawGeomMouse( action, pos, &drawCmdContext ); - + return DrawGeomMouse( action, pos, &drawCmdContext); + case C_TEXT: + if (drawCmdContext.Op == OP_BEZLIN) return CmdBezCurve(action, pos); + return DrawGeomMouse( action, pos, &drawCmdContext); case C_OK: if (drawCmdContext.Op == OP_BEZLIN) return CmdBezCurve(act2, pos); - return DrawGeomMouse( (0x0D<<8|wActionText), pos, &drawCmdContext ); + return DrawGeomMouse( (0x0D<<8|wActionText), pos, &drawCmdContext); + /*DrawOk( NULL );*/ case C_FINISH: if (drawCmdContext.Op == OP_BEZLIN) return CmdBezCurve(act2, pos); - return DrawGeomMouse( (0x0D<<8|wActionText), pos, &drawCmdContext ); + return DrawGeomMouse( (0x0D<<8|wActionText), pos, &drawCmdContext); /*DrawOk( NULL );*/ case C_REDRAW: if (drawCmdContext.Op == OP_BEZLIN) return CmdBezCurve(act2, pos); - return DrawGeomMouse( action, pos, &drawCmdContext ); + return DrawGeomMouse( action, pos, &drawCmdContext); + + case C_CMDMENU: + if (drawCmdContext.Op == OP_BEZLIN) return C_CONTINUE; + return DrawGeomMouse( action, pos, &drawCmdContext); default: return C_CONTINUE; @@ -1172,6 +2559,7 @@ static STATUS_T CmdDraw( wAction_t action, coOrd pos ) #include "bitmaps/dpoly.xpm" #include "bitmaps/dfilpoly.xpm" #include "bitmaps/dbezier.xpm" +#include "bitmaps/dpolyline.xpm" typedef struct { char **xpm; @@ -1195,16 +2583,18 @@ static drawData_t dcurveCmds[] = { { dbezier_xpm, OP_BEZLIN, N_("Bezier Curve"), N_("Draw Bezier"), "cmdDrawBezierCurve", ACCL_DRAWBEZLINE } }; static drawData_t dcircleCmds[] = { /*{ dcircle1_xpm, OP_CIRCLE1, "Circle Fixed Radius", "Draw Fixed Radius Circle", "cmdDrawCircleFixedRadius", ACCL_DRAWCIRCLE1 },*/ - { dcircle2_xpm, OP_CIRCLE3, N_("Circle Tangent"), N_("Draw Circle from Tangent"), "cmdDrawCircleTangent", ACCL_DRAWCIRCLE2 }, - { dcircle3_xpm, OP_CIRCLE2, N_("Circle Center"), N_("Draw Circle from Center"), "cmdDrawCircleCenter", ACCL_DRAWCIRCLE3 }, + { dcircle3_xpm, OP_CIRCLE3, N_("Circle Tangent"), N_("Draw Circle from Tangent"), "cmdDrawCircleTangent", ACCL_DRAWCIRCLE2 }, + { dcircle2_xpm, OP_CIRCLE2, N_("Circle Center"), N_("Draw Circle from Center"), "cmdDrawCircleCenter", ACCL_DRAWCIRCLE3 }, /*{ dflcrcl1_xpm, OP_FILLCIRCLE1, "Circle Filled Fixed Radius", "Draw Fixed Radius Filled Circle", "cmdDrawFilledCircleFixedRadius", ACCL_DRAWFILLCIRCLE1 },*/ - { dflcrcl2_xpm, OP_FILLCIRCLE3, N_("Circle Filled Tangent"), N_("Draw Filled Circle from Tangent"), "cmdDrawFilledCircleTangent", ACCL_DRAWFILLCIRCLE2 }, - { dflcrcl3_xpm, OP_FILLCIRCLE2, N_("Circle Filled Center"), N_("Draw Filled Circle from Center"), "cmdDrawFilledCircleCenter", ACCL_DRAWFILLCIRCLE3 } }; + { dflcrcl3_xpm, OP_FILLCIRCLE3, N_("Circle Filled Tangent"), N_("Draw Filled Circle from Tangent"), "cmdDrawFilledCircleTangent", ACCL_DRAWFILLCIRCLE2 }, + { dflcrcl2_xpm, OP_FILLCIRCLE2, N_("Circle Filled Center"), N_("Draw Filled Circle from Center"), "cmdDrawFilledCircleCenter", ACCL_DRAWFILLCIRCLE3 } }; static drawData_t dshapeCmds[] = { { dbox_xpm, OP_BOX, N_("Box"), N_("Draw Box"), "cmdDrawBox", ACCL_DRAWBOX }, { dfilbox_xpm, OP_FILLBOX, N_("Filled Box"), N_("Draw Filled Box"), "cmdDrawFilledBox", ACCL_DRAWFILLBOX }, - { dpoly_xpm, OP_POLY, N_("Poly Line"), N_("Draw Polyline"), "cmdDrawPolyline", ACCL_DRAWPOLYLINE }, - { dfilpoly_xpm, OP_FILLPOLY, N_("Polygon"), N_("Draw Polygon"), "cmdDrawPolygon", ACCL_DRAWPOLYGON } }; + { dpoly_xpm, OP_POLY, N_("Polygon"), N_("Draw Polygon"), "cmdDrawPolygon", ACCL_DRAWPOLY }, + { dfilpoly_xpm, OP_FILLPOLY, N_("Filled Polygon"), N_("Draw Filled Polygon"), "cmdDrawFilledPolygon", ACCL_DRAWFILLPOLYGON }, + { dpolyline_xpm, OP_POLYLINE, N_("PolyLine"), N_("Draw PolyLine"), "cmdDrawPolyline", ACCL_DRAWPOLYLINE }, +}; typedef struct { char * helpKey; @@ -1223,7 +2613,7 @@ static drawStuff_t drawStuff[4] = { { "cmdDrawLineSetCmd", N_("Straight Objects"), N_("Draw Straight Objects"), 4, dlineCmds }, { "cmdDrawCurveSetCmd", N_("Curved Lines"), N_("Draw Curved Lines"), 5, dcurveCmds }, { "cmdDrawCircleSetCmd", N_("Circle Lines"), N_("Draw Circles"), 4, dcircleCmds }, - { "cmdDrawShapeSetCmd", N_("Shapes"), N_("Draw Shapes"), 4, dshapeCmds} }; + { "cmdDrawShapeSetCmd", N_("Shapes"), N_("Draw Shapes"), 5, dshapeCmds} }; static void ChangeDraw( long changes ) @@ -1247,13 +2637,58 @@ static void DrawDlgUpdate( int inx, void * valueP ) { - if (drawCmdContext.Op == OP_BEZLIN) { - if ( (inx == 0 && pg->paramPtr[inx].valueP == &drawCmdContext.Width) || - (inx == 1 && pg->paramPtr[inx].valueP == &lineColor)) - { - lineWidth = drawCmdContext.Width; - UpdateParms(lineColor, lineWidth); - } + if (inx==3) { + if (drawCmdContext.Op == OP_BEZLIN) { + if ( (inx == 0 && pg->paramPtr[inx].valueP == &drawCmdContext.line_Width) || + (inx == 1 && pg->paramPtr[inx].valueP == &lineColor)) + { + lineWidth = drawCmdContext.line_Width; + UpdateParms(lineColor, lineWidth); + } + } + } + if (inx >=6 ) { + if (drawCmdContext.Op == OP_CIRCLE1 || + drawCmdContext.Op == OP_FILLCIRCLE1 || + drawCmdContext.Op == OP_CIRCLE2 || + drawCmdContext.Op == OP_FILLCIRCLE2 || + drawCmdContext.Op == OP_CIRCLE3 || + drawCmdContext.Op == OP_FILLCIRCLE3) { + coOrd pos = zero; + DrawGeomMouse(C_UPDATE,pos,&drawCmdContext); + } + if (drawCmdContext.Op == OP_CURVE1 || + drawCmdContext.Op == OP_CURVE2 || + drawCmdContext.Op == OP_CURVE3 || + drawCmdContext.Op == OP_CURVE4 ) { + coOrd pos = zero; + DrawGeomMouse(C_UPDATE,pos,&drawCmdContext); + } + if (drawCmdContext.Op == OP_LINE || + drawCmdContext.Op == OP_BENCH|| + drawCmdContext.Op == OP_TBLEDGE) { + coOrd pos = zero; + DrawGeomMouse(C_UPDATE,pos,&drawCmdContext); + } + + if (drawCmdContext.Op == OP_BOX || + drawCmdContext.Op == OP_FILLBOX ){ + coOrd pos = zero; + DrawGeomMouse(C_UPDATE,pos,&drawCmdContext); + } + + if (drawCmdContext.Op == OP_POLY || + drawCmdContext.Op == OP_FILLPOLY || + drawCmdContext.Op == OP_POLYLINE) { + coOrd pos = zero; + DrawGeomMouse(C_UPDATE,pos,&drawCmdContext); + } + ParamLoadControl(&drawPG,drawAngleInx); //Force Angle change out + //if (pg->paramPtr[inx].enter_pressed) { + // coOrd pos = zero; + // DrawGeomMouse((0x0D<<8)|(C_TEXT&0xFF),pos,&drawCmdContext); + // CmdDraw(C_START,pos); + //} } if ( inx >= 0 && pg->paramPtr[inx].valueP == &benchChoice ) @@ -1272,13 +2707,15 @@ EXPORT void InitCmdDraw( wMenu_p menu ) benchColor = wDrawFindColor( wRGB(255,192,0) ); ParamCreateControls( &drawPG, DrawDlgUpdate ); + ParamCreateControls( &drawModPG, DrawModDlgUpdate) ; + for ( inx1=0; inx1<4; inx1++ ) { dsp = &drawStuff[inx1]; ButtonGroupBegin( _(dsp->menuTitle), dsp->helpKey, _(dsp->stickyLabel) ); for ( inx2=0; inx2<dsp->cnt; inx2++ ) { ddp = &dsp->data[inx2]; icon = wIconCreatePixMap( ddp->xpm ); - AddMenuButton( menu, CmdDraw, ddp->helpKey, _(ddp->cmdName), icon, LEVEL0_50, IC_STICKY|IC_POPUP2, ddp->acclKey, (void *)(intptr_t)ddp->OP ); + AddMenuButton( menu, CmdDraw, ddp->helpKey, _(ddp->cmdName), icon, LEVEL0_50, IC_STICKY|IC_POPUP2|IC_WANT_MOVE, ddp->acclKey, (void *)(intptr_t)ddp->OP ); } ButtonGroupEnd(); } @@ -1327,7 +2764,8 @@ EXPORT track_p NewText( ANGLE_T angle, char * text, CSIZE_T textSize, - wDrawColor color ) + wDrawColor color, + BOOL_T boxed) { trkSeg_t tempSeg; track_p trk; @@ -1339,6 +2777,7 @@ EXPORT track_p NewText( tempSeg.u.t.fontP = NULL; tempSeg.u.t.fontSize = textSize; tempSeg.u.t.string = MyStrdup( text ); + tempSeg.u.t.boxed = boxed; trk = MakeDrawFromSeg1( index, pos, angle, &tempSeg ); return trk; } @@ -1364,20 +2803,127 @@ EXPORT BOOL_T ReadText( char * line ) return FALSE; } - char * old = text; - text = ConvertFromEscapedText(text); - MyFree(old); - - trk = NewText( index, pos, angle, text, textSize, color ); + trk = NewText( index, pos, angle, text, textSize, color, FALSE ); SetTrkLayer( trk, layer ); MyFree(text); return TRUE; } +void MenuMode(int mode) { + if ( infoSubst ) { + InfoSubstituteControls( NULL, NULL ); + infoSubst = FALSE; + } + if (mode == 1) { + DrawGeomOriginMove(C_START,zero,&drawModCmdContext); + InfoMessage("Origin Mode"); + } else { + DrawGeomModify(C_START,zero,&drawModCmdContext); + InfoMessage("Points Mode"); + } +} + +void MenuEnter(int key) { + int action; + action = C_TEXT; + action |= key<<8; + if (drawModCmdContext.rotate_state) + DrawGeomOriginMove(action,zero,&drawModCmdContext); + else + DrawGeomModify(action,zero,&drawModCmdContext); +} + +void MenuLine(int key) { + struct extraData * xx = GetTrkExtraData(drawModCmdContext.trk); + if ( drawModCmdContext.type==SEG_STRLIN || drawModCmdContext.type==SEG_CRVLIN || drawModCmdContext.type==SEG_POLY ) { + switch(key) { + case '0': + xx->lineType = DRAWLINESOLID; + break; + case '1': + xx->lineType = DRAWLINEDASH; + break; + case '2': + xx->lineType = DRAWLINEDOT; + break; + case '3': + xx->lineType = DRAWLINEDASHDOT; + break; + case '4': + xx->lineType = DRAWLINEDASHDOTDOT; + break; + case '5': + xx->lineType = DRAWLINECENTER; + break; + case '6': + xx->lineType = DRAWLINEPHANTOM; + break; + } + MainRedraw(); // MenuLine + } +} + +EXPORT void SetLineType( track_p trk, int width ) { + if (QueryTrack(trk, Q_IS_DRAW)) { + struct extraData * xx = GetTrkExtraData(trk); + if ( xx->segs[0].type==SEG_STRLIN || xx->segs[0].type==SEG_CRVLIN || xx->segs[0].type==SEG_POLY) { + switch(width) { + case 0: + xx->lineType = DRAWLINESOLID; + break; + case 1: + xx->lineType = DRAWLINEDASH; + break; + case 2: + xx->lineType = DRAWLINEDOT; + break; + case 3: + xx->lineType = DRAWLINEDASHDOT; + break; + case 4: + xx->lineType = DRAWLINEDASHDOTDOT; + break; + case 5: + xx->lineType = DRAWLINECENTER; + break; + case 6: + xx->lineType = DRAWLINEPHANTOM; + break; + } + } + } +} EXPORT void InitTrkDraw( void ) { T_DRAW = InitObject( &drawCmds ); AddParam( "TABLEEDGE", ReadTableEdge ); AddParam( "TEXT", ReadText ); + + drawModDelMI = MenuRegister( "Modify Draw Edit Menu" ); + drawModClose = wMenuPushCreate( drawModDelMI, "", _("Close Polygon - 'g'"), 0, (wMenuCallBack_p)MenuEnter, (void*) 'g'); + drawModOpen = wMenuPushCreate( drawModDelMI, "", _("Make PolyLine - 'l'"), 0, (wMenuCallBack_p)MenuEnter, (void*) 'l'); + drawModFill = wMenuPushCreate( drawModDelMI, "", _("Fill Polygon - 'f'"), 0, (wMenuCallBack_p)MenuEnter, (void*) 'f'); + drawModEmpty = wMenuPushCreate( drawModDelMI, "", _("Empty Polygon - 'u'"), 0, (wMenuCallBack_p)MenuEnter, (void*) 'u'); + wMenuSeparatorCreate( drawModDelMI ); + drawModPointsMode = wMenuPushCreate( drawModDelMI, "", _("Points Mode - 'p'"), 0, (wMenuCallBack_p)MenuMode, (void*) 0 ); + drawModDel = wMenuPushCreate( drawModDelMI, "", _("Delete Selected Point - 'Del'"), 0, (wMenuCallBack_p)MenuEnter, (void*) 127 ); + drawModVertex = wMenuPushCreate( drawModDelMI, "", _("Vertex Point - 'v'"), 0, (wMenuCallBack_p)MenuEnter, (void*) 'v' ); + drawModRound = wMenuPushCreate( drawModDelMI, "", _("Round Corner - 'r'"), 0, (wMenuCallBack_p)MenuEnter, (void*) 'r' ); + drawModSmooth = wMenuPushCreate( drawModDelMI, "", _("Smooth Corner - 's'"), 0, (wMenuCallBack_p)MenuEnter, (void*) 's' ); + wMenuSeparatorCreate( drawModDelMI ); + drawModLinMI = wMenuMenuCreate( drawModDelMI, "", _("LineType...") ); + drawModSolid = wMenuPushCreate( drawModLinMI, "", _("Solid Line"), 0, (wMenuCallBack_p)MenuLine, (void*) '0' ); + drawModDot = wMenuPushCreate( drawModLinMI, "", _("Dashed Line"), 0, (wMenuCallBack_p)MenuLine, (void*) '1' ); + drawModDash = wMenuPushCreate( drawModLinMI, "", _("Dotted Line"), 0, (wMenuCallBack_p)MenuLine, (void*) '2' ); + drawModDashDot = wMenuPushCreate( drawModLinMI, "", _("Dash-Dot Line"), 0, (wMenuCallBack_p)MenuLine, (void*) '3' ); + drawModDashDotDot = wMenuPushCreate( drawModLinMI, "", _("Dash-Dot-Dot Line"), 0, (wMenuCallBack_p)MenuLine, (void*) '4' ); + drawModCenterDot = wMenuPushCreate( drawModLinMI, "", _("Center-Dot Line"), 0, (wMenuCallBack_p)MenuLine, (void*) '5' ); + drawModPhantom = wMenuPushCreate( drawModLinMI, "", _("Phantom-Dot Line"), 0, (wMenuCallBack_p)MenuLine, (void*) '6' ); + wMenuSeparatorCreate( drawModDelMI ); + drawModriginMode = wMenuPushCreate( drawModDelMI, "", _("Origin Mode - 'o'"), 0, (wMenuCallBack_p)MenuMode, (void*) 1 ); + drawModOrigin = wMenuPushCreate( drawModDelMI, "", _("Reset Origin - '0'"), 0, (wMenuCallBack_p)MenuEnter, (void*) '0' ); + drawModLast = wMenuPushCreate( drawModDelMI, "", _("Origin to Selected - 'l'"), 0, (wMenuCallBack_p)MenuEnter, (void*) 'l' ); + drawModCenter = wMenuPushCreate( drawModDelMI, "", _("Origin to Middle - 'm'"), 0, (wMenuCallBack_p)MenuEnter, (void*) 'm'); + } |