From b623f5953691b2a0614e6f1f4def86bdbb9a4113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sat, 8 Aug 2020 11:53:00 +0200 Subject: New upstream version 5.2.0Beta2.1 --- app/bin/cselect.c | 2250 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 1774 insertions(+), 476 deletions(-) (limited to 'app/bin/cselect.c') diff --git a/app/bin/cselect.c b/app/bin/cselect.c index 8ff68c0..4e4e8eb 100644 --- a/app/bin/cselect.c +++ b/app/bin/cselect.c @@ -23,9 +23,11 @@ #include #include +#include "draw.h" #include "ccurve.h" #include "tcornu.h" #include "tbezier.h" +#include "track.h" #define PRIVATE_EXTRADATA #include "compound.h" #include "cselect.h" @@ -38,6 +40,10 @@ #include "param.h" #include "track.h" #include "utility.h" +#include "draw.h" +#include "misc.h" +#include "trackx.h" + #include "bitmaps/bmendpt.xbm" #include "bitmaps/bma0.xbm" @@ -59,10 +65,12 @@ struct extraData { char junk[2000]; }; static wDrawBitMap_p endpt_bm; static wDrawBitMap_p angle_bm[4]; +track_p IsInsideABox(coOrd pos); + +static track_p moveDescTrk; +static coOrd moveDescPos; - long quickMove = 0; - BOOL_T importMove = 0; - int incrementalDrawLimit = 20; +int incrementalDrawLimit = 20; static int microCount = 0; static dynArr_t tlist_da; @@ -71,12 +79,169 @@ static dynArr_t tlist_da; #define TlistAppend( T ) \ { DYNARR_APPEND( track_p, tlist_da, 10 );\ Tlist(tlist_da.cnt-1) = T; } -static track_p *tlist2 = NULL; + +BOOL_T TListSearch(track_p T) { + for (int i=0;i 0 && selectedTrackCount == 0 ) + if ( inx > 0 && (selectedTrackCount == 0) && !display_only ) return; trk = Tlist(inx); if (inx!=0 && - GetTrkSelected(trk)) + GetTrkSelected(trk)) { + if (display_only) + DrawTrack(trk,&tempD,wDrawColorPreviewSelected ); + continue; + } else if (GetTrkSelected(trk)) { + if (display_only) + DrawTrack(trk,&tempD,wDrawColorPreviewUnselected); continue; + } for (ep=0; ep0) { @@ -341,6 +669,7 @@ EXPORT void SelectDelete( void ) wDrawDelayUpdate( mainD.d, TRUE ); wDrawDelayUpdate( mapD.d, TRUE ); DoSelectedTracks( DeleteTrack ); + DoRedraw(); // SelectDelete wDrawDelayUpdate( mainD.d, FALSE ); wDrawDelayUpdate( mapD.d, FALSE ); selectedTrackCount = 0; @@ -368,8 +697,10 @@ static BOOL_T FlipHidden( track_p trk, BOOL_T junk ) if ( drawTunnel == 0 ) flipHiddenDoSelectRecount = TRUE; if (GetTrkVisible(trk)) { - ClrTrkBits( trk, TB_VISIBLE|(drawTunnel==0?TB_SELECTED:0) ); - } else { + ClrTrkBits( trk, TB_VISIBLE|(drawTunnel==0?(TB_SELECTED|TB_SELREDRAW):0) ); + ClrTrkBits (trk, TB_BRIDGE); + ClrTrkBits (trk, TB_NOTIES); +; } else { SetTrkBits( trk, TB_VISIBLE ); } /*DrawNewTrack( trk );*/ @@ -382,6 +713,29 @@ static BOOL_T FlipHidden( track_p trk, BOOL_T junk ) return TRUE; } +static BOOL_T FlipBridge( track_p trk, BOOL_T junk ) +{ + UndoModify( trk ); + if (GetTrkBridge(trk)) { + ClrTrkBits( trk, TB_BRIDGE ); + } else { + SetTrkBits( trk, TB_BRIDGE ); + SetTrkBits( trk, TB_VISIBLE); + } + return TRUE; +} + +static BOOL_T FlipTies( track_p trk, BOOL_T junk ) +{ + UndoModify( trk ); + if (GetTrkNoTies(trk)) { + ClrTrkBits( trk, TB_NOTIES ); + } else { + SetTrkBits( trk, TB_NOTIES ); + SetTrkBits( trk, TB_VISIBLE ); + } + return TRUE; +} EXPORT void SelectTunnel( void ) { @@ -401,6 +755,39 @@ EXPORT void SelectTunnel( void ) SelectRecount(); } +EXPORT void SelectBridge( void ) +{ + if (SelectedTracksAreFrozen()) + return; + if (selectedTrackCount>0) { + flipHiddenDoSelectRecount = FALSE; + UndoStart( _("Bridge Tracks "), "bridge" ); + wDrawDelayUpdate( mainD.d, TRUE ); + DoSelectedTracks( FlipBridge ); + wDrawDelayUpdate( mainD.d, FALSE ); + UndoEnd(); + } else { + ErrorMessage( MSG_NO_SELECTED_TRK ); + } + MainRedraw(); // SelectBridge +} + +EXPORT void SelectTies( void ) +{ + if (SelectedTracksAreFrozen()) + return; + if (selectedTrackCount>0) { + flipHiddenDoSelectRecount = FALSE; + UndoStart( _("Ties Tracks "), "noties" ); + wDrawDelayUpdate( mainD.d, TRUE ); + DoSelectedTracks( FlipTies ); + wDrawDelayUpdate( mainD.d, FALSE ); + UndoEnd(); + } else { + ErrorMessage( MSG_NO_SELECTED_TRK ); + } + MainRedraw(); // SelectTies +} void SelectRecount( void ) { @@ -445,6 +832,7 @@ EXPORT void SelectCurrentLayer( void ) SelectOneTrack( trk, TRUE ); } } + RedrawSelectedTracksBoundary(); } @@ -530,8 +918,7 @@ EXPORT void DoRefreshCompound( void ) DoSelectedTracks( RefreshCompound ); RefreshCompound( NULL, FALSE ); UndoEnd(); - MainRedraw(); - MapRedraw(); + MainRedraw(); // DoRefreshCompound } else { ErrorMessage( MSG_NO_SELECTED_TRK ); } @@ -539,15 +926,12 @@ EXPORT void DoRefreshCompound( void ) static drawCmd_t tempSegsD = { - NULL, &tempSegDrawFuncs, DC_GROUP, 1, 0.0, {0.0, 0.0}, {0.0, 0.0}, Pix2CoOrd, CoOrd2Pix }; + NULL, &tempSegDrawFuncs, 0, 1, 0.0, {0.0, 0.0}, {0.0, 0.0}, Pix2CoOrd, CoOrd2Pix }; EXPORT void WriteSelectedTracksToTempSegs( void ) { track_p trk; - long oldOptions; DYNARR_RESET( trkSeg_t, tempSegs_da ); tempSegsD.dpi = mainD.dpi; - oldOptions = tempSegDrawFuncs.options; - tempSegDrawFuncs.options = wDrawOptTemp; for ( trk=NULL; TrackIterate(&trk); ) { if ( GetTrkSelected( trk ) ) { if ( IsTrack( trk ) ) @@ -557,7 +941,6 @@ EXPORT void WriteSelectedTracksToTempSegs( void ) SetTrkBits( trk, TB_SELECTED ); } } - tempSegDrawFuncs.options = oldOptions; } static char rescaleFromScale[20]; @@ -619,6 +1002,7 @@ static BOOL_T RescaleDoIt( track_p trk, BOOL_T junk ) { EPINX_T ep, ep1; track_p trk1; + UndrawNewTrack( trk ); UndoModify(trk); if ( rescalePercent != 100.0 ) { for (ep=0; eporig, d->size, lo, hi ) ) continue; } + if (color != wDrawColorWhite) + ClrTrkBits(trk, TB_UNDRAWN); DrawTrack( trk, d, color ); + if (color == wDrawColorWhite) + SetTrkBits( trk, TB_UNDRAWN ); } /*wDrawDelayUpdate( d->d, FALSE );*/ } @@ -865,7 +1221,7 @@ static ANGLE_T moveAngle; static coOrd moveD_hi, moveD_lo; static drawCmd_t moveD = { - NULL, &tempDrawFuncs, DC_SIMPLE, 1, 0.0, {0.0, 0.0}, {0.0, 0.0}, Pix2CoOrd, CoOrd2Pix }; + NULL, &tempSegDrawFuncs, DC_SIMPLE, 1, 0.0, {0.0, 0.0}, {0.0, 0.0}, Pix2CoOrd, CoOrd2Pix }; @@ -884,61 +1240,56 @@ static void AccumulateTracks( void ) coOrd lo, hi; /*wDrawDelayUpdate( moveD.d, TRUE );*/ - if (quickMove == MOVE_FAST) - moveD.options |= DC_QUICK; - for ( inx = 0; inx= moveD_lo.x && - lo.y <= moveD_hi.y && hi.y >= moveD_lo.y ) { - if (quickMove != MOVE_QUICK) { -#if defined(WINDOWS) && ! defined(WIN32) - if ( tempSegs_da.cnt+100 > 65500 / sizeof(*(trkSeg_p)NULL) ) { - ErrorMessage( MSG_TOO_MANY_SEL_TRKS ); - - quickMove = MOVE_QUICK; - } else -#endif - DrawTrack( trk, &moveD, wDrawColorBlack ); - } - tlist2[inx] = NULL; - movedCnt++; + movedCnt =0; + for ( inx = 0; inx= moveD_lo.x && + lo.y <= moveD_hi.y && hi.y >= moveD_lo.y ) { + if (!QueryTrack(trk,Q_IS_CORNU)) + DrawTrack( trk, &moveD, wDrawColorBlack ); } + movedCnt++; } - } - moveD.options &= ~DC_QUICK; + } InfoCount( movedCnt ); /*wDrawDelayUpdate( moveD.d, FALSE );*/ } +static void AddEndCornus() { + for (int i=0;i=0;j--) { + tc = GetTrkEndTrk(trk,j); + if (tc && !GetTrkSelected(tc) && QueryTrack(tc,Q_IS_CORNU) && !QueryTrack(trk,Q_IS_CORNU)) { //On end and cornu + SelectOneTrack( tc, TRUE ); + DYNARR_APPEND(track_p,tlist_da,1); //Add to selected list + DYNARR_LAST(track_p,tlist_da) = tc; + } + } + } +} + static void GetMovedTracks( BOOL_T undraw ) { - wSetCursor( wCursorWait ); + wSetCursor( mainD.d, wCursorWait ); DYNARR_RESET( track_p, tlist_da ); DoSelectedTracks( AddSelectedTrack ); - tlist2 = (track_p*)MyRealloc( tlist2, (tlist_da.cnt+1) * sizeof *(track_p*)0 ); - if (tlist_da.ptr) - memcpy( tlist2, tlist_da.ptr, (tlist_da.cnt) * sizeof *(track_p*)0 ); - tlist2[tlist_da.cnt] = NULL; + AddEndCornus(); //Include Cornus that are attached at ends of selected DYNARR_RESET( trkSeg_p, tempSegs_da ); - moveD = mainD; - moveD.funcs = &tempSegDrawFuncs; - moveD.options = DC_SIMPLE; - tempSegDrawFuncs.options = wDrawOptTemp; moveOrig = mainD.orig; movedCnt = 0; InfoCount(0); - wSetCursor( wCursorNormal ); + wSetCursor( mainD.d, defaultCursor ); moveD_hi = moveD_lo = mainD.orig; moveD_hi.x += mainD.size.x; moveD_hi.y += mainD.size.y; AccumulateTracks(); if (undraw) { DrawSelectedTracksD( &mainD, wDrawColorWhite ); - /*DrawSegs( &mainD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, - trackGauge, wDrawColorBlack );*/ } } @@ -989,48 +1340,50 @@ static void DrawMovedTracks( void ) { int inx; track_p trk; - track_p other; - EPINX_T i; - coOrd pos; - wDrawBitMap_p bm; - ANGLE_T a; - int ia; - - if ( quickMove != MOVE_QUICK) { - DrawSegs( &tempD, moveOrig, moveAngle, &tempSegs(0), tempSegs_da.cnt, - 0.0, wDrawColorBlack ); - return; - } + dynArr_t cornu_segs; + + DrawSegs( &tempD, moveOrig, moveAngle, &tempSegs(0), tempSegs_da.cnt, + 0.0, wDrawColorBlack ); + for ( inx=0; inx=0; i--) { - pos = GetTrkEndPos(trk,i); - if (!move0B) { - Rotate( &pos, zero, moveAngle ); - } - pos.x += moveOrig.x; - pos.y += moveOrig.y; - if ((other=GetTrkEndTrk(trk,i)) == NULL || - !GetTrkSelected(other)) { - bm = endpt_bm; - } else if (other != NULL && GetTrkIndex(trk) < GetTrkIndex(other)) { - a = GetTrkEndAngle(trk,i)+22.5; - if (!move0B) - a += moveAngle; - a = NormalizeAngle( a ); - if (a>=180.0) - a -= 180.0; - ia = (int)(a/45.0); - bm = angle_bm[ia]; - } else { - continue; + if (QueryTrack(trk,Q_IS_CORNU)) { + DYNARR_RESET(trkSeg_t,cornu_segs); + coOrd pos[2]; + DIST_T radius[2]; + ANGLE_T angle[2]; + coOrd center[2]; + trackParams_t trackParams; + if (GetTrackParams(PARAMS_CORNU, trk, zero, &trackParams)) { + for (int i=0;i<2;i++) { + pos[i] = trackParams.cornuEnd[i]; + center[i] = trackParams.cornuCenter[i]; + angle[i] = trackParams.cornuAngle[i]; + radius[i] = trackParams.cornuRadius[i]; + if (!GetTrkEndTrk(trk,i) || + (GetTrkEndTrk(trk,i) && GetTrkSelected(GetTrkEndTrk(trk,i)))) { + if (!move0B) { + Rotate( &pos[i], zero, moveAngle ); + Rotate( ¢er[i],zero, moveAngle ); + angle[i] = NormalizeAngle(angle[i]+moveAngle); + } + pos[i].x += moveOrig.x; + pos[i].y += moveOrig.y; + center[i].x +=moveOrig.x; + center[i].y +=moveOrig.y; + } + } + CallCornu0(&pos[0],¢er[0],&angle[0],&radius[0],&cornu_segs, FALSE); + trkSeg_p cornu_p = &DYNARR_N(trkSeg_t,cornu_segs,0); + + DrawSegsO(&tempD, trk, zero, 0.0, cornu_p,cornu_segs.cnt, + GetTrkGauge(trk), wDrawColorBlack, DTS_LEFT|DTS_RIGHT ); } - if ( !OFF_MAIND( pos, pos ) ) - DrawBitMap( &tempD, pos, bm, selectedColor ); + } + } + return; } @@ -1041,7 +1394,8 @@ static void MoveTracks( BOOL_T rotate, coOrd base, coOrd orig, - ANGLE_T angle ) + ANGLE_T angle, + BOOL_T undo) { track_p trk, trk1; EPINX_T ep, ep1; @@ -1051,48 +1405,47 @@ static void MoveTracks( DIST_T endRadius; coOrd endCenter; - wSetCursor( wCursorWait ); + wSetCursor( mainD.d, wCursorWait ); /*UndoStart( "Move/Rotate Tracks", "move/rotate" );*/ if (tlist_da.cnt <= incrementalDrawLimit) { - DrawMapBoundingBox( FALSE ); - if (eraseFirst) + if (eraseFirst) { DrawSelectedTracksD( &mainD, wDrawColorWhite ); - DrawSelectedTracksD( &mapD, wDrawColorWhite ); + DrawSelectedTracksD( &mapD, wDrawColorWhite ); + } } for ( inx=0; inx incrementalDrawLimit) { - DoRedraw(); - } else { - DrawSelectedTracksD( &mainD, wDrawColorBlack ); - DrawSelectedTracksD( &mapD, wDrawColorBlack ); - DrawMapBoundingBox( TRUE ); } - wSetCursor( wCursorNormal ); - UndoEnd(); - tempSegDrawFuncs.options = 0; + ClrAllTrkBits(TB_UNDRAWN); + DoRedraw(); + wSetCursor( mainD.d, defaultCursor ); + if (undo) UndoEnd(); InfoCount( trackCount ); } @@ -1159,7 +1528,7 @@ void MoveToJoin( angle += 180.0; angle = NormalizeAngle( angle ); GetMovedTracks( FALSE ); - MoveTracks( TRUE, TRUE, TRUE, base, orig, angle ); + MoveTracks( TRUE, TRUE, TRUE, base, orig, angle, TRUE ); UndrawNewTrack( trk0 ); UndrawNewTrack( trk1 ); ConnectTracks( trk0, ep0, trk1, ep1 ); @@ -1176,6 +1545,145 @@ void FreeTempStrings() { } } } + + +wBool_t FindEndIntersection(coOrd base, coOrd orig, ANGLE_T angle, track_p * t1, EPINX_T * ep1, track_p * t2, EPINX_T * ep2) { + *ep1 = -1; + *ep2 = -1; + *t1 = NULL; + *t2 = NULL; + for ( int inx=0; inx=0) { + DIST_T d = FindDistance(pos1,GetTrkEndPos(tt,epp)); + if (IsClose(d)) { + *ep1 = epp; + *ep2 = i; + *t1 = tt; + *t2 = ts; + return TRUE; + } + } else { + epp = PickEndPoint(pos2,tt); //Any close end point (even joined) + if (epp>=0) { + ct = GetTrkEndTrk(tt,epp); + if (ct && GetTrkSelected(ct)) { //Point is junction to selected track - so will be broken + DIST_T d = FindDistance(pos1,GetTrkEndPos(tt,epp)); + if (IsClose(d)) { + *ep1 = epp; + *ep2 = i; + *t1 = tt; + *t2 = ts; + return TRUE; + } + } + } + } + } + } + } + } + return FALSE; +} + +void DrawHighlightLayer(int layer) { + track_p ts = NULL; + BOOL_T initial = TRUE; + coOrd layer_hi = zero,layer_lo = zero; + while ( TrackIterate( &ts ) ) { + if ( !GetLayerVisible( GetTrkLayer( ts))) continue; + if (!GetTrkSelected(ts)) continue; + if (GetTrkLayer(ts) != layer) continue; + coOrd hi,lo; + GetBoundingBox(ts, &hi, &lo); + if (initial) { + layer_hi = hi; + layer_lo = lo; + initial = FALSE; + } else { + if (layer_hi.x < hi.x ) layer_hi.x = hi.x; + if (layer_hi.y < hi.y ) layer_hi.y = hi.y; + if (layer_lo.x > lo.x ) layer_lo.x = lo.x; + if (layer_lo.y > lo.y ) layer_lo.y = lo.y; + } + } + wPos_t margin = (wPos_t)(10.5*mainD.scale/mainD.dpi); + layer_hi.x +=margin; + layer_hi.y +=margin; + layer_lo.x -=margin; + layer_lo.y -=margin; + + wPos_t rect[4][2]; + int type[4]; + coOrd top_left, bot_right; + top_left.x = layer_lo.x; top_left.y = layer_hi.y; + bot_right.x = layer_hi.x; bot_right.y = layer_lo.y; + type[0] = type[1] = type[2] = type[3] = 0; + mainD.CoOrd2Pix(&mainD,layer_lo,&rect[0][0],&rect[0][1]); + mainD.CoOrd2Pix(&mainD,top_left,&rect[1][0],&rect[1][1]); + mainD.CoOrd2Pix(&mainD,layer_hi,&rect[2][0],&rect[2][1]); + mainD.CoOrd2Pix(&mainD,bot_right,&rect[3][0],&rect[3][1]); + wDrawPolygon(tempD.d,rect,(wPolyLine_e *)type,4,wDrawColorPowderedBlue,0,wDrawLineDash,wDrawOptTemp,0,0); +} + +void SetUpMenu2(coOrd pos, track_p trk) { + wMenuPushEnable( menuPushModify,FALSE); + wMenuPushEnable(descriptionMI,FALSE); + wMenuPushEnable( rotateAlignMI, FALSE ); + wMenuPushEnable( hideMI, FALSE ); + wMenuPushEnable( bridgeMI, FALSE ); + wMenuPushEnable( tiesMI, FALSE ); + if ((trk) && + QueryTrack(trk,Q_CAN_ADD_ENDPOINTS)) { //Turntable snap to center if within 1/4 radius + trackParams_t trackParams; + if (GetTrackParams(PARAMS_CORNU, trk, pos, &trackParams)) { + DIST_T dist = FindDistance(pos, trackParams.ttcenter); + if (dist < trackParams.ttradius/4) { + cmdMenuPos = trackParams.ttcenter; + } + } + } + if (trk && !QueryTrack( trk, Q_IS_DRAW )) { + wMenuPushEnable( hideMI, TRUE ); + wMenuPushEnable( bridgeMI, TRUE ); + wMenuPushEnable( tiesMI, TRUE ); + } + if (trk) { + wMenuPushEnable( menuPushModify, + (QueryTrack( trk, Q_CAN_MODIFY_CONTROL_POINTS ) || + QueryTrack( trk, Q_IS_CORNU ) || + (QueryTrack( trk, Q_IS_DRAW ) && !QueryTrack( trk, Q_IS_TEXT )) || + QueryTrack( trk, Q_IS_ACTIVATEABLE))); + } + if ((trk)) { + wMenuPushEnable(descriptionMI, QueryTrack( trk, Q_HAS_DESC )); + moveDescTrk = trk; + moveDescPos = pos; + } + if (selectedTrackCount>0) + wMenuPushEnable( rotateAlignMI, TRUE ); +} + static STATUS_T CmdMove( wAction_t action, @@ -1185,9 +1693,16 @@ static STATUS_T CmdMove( static coOrd orig; static int state; - switch( action&0xFF) { + static EPINX_T ep1; + static EPINX_T ep2; + static track_p t1; + static track_p t2; + static BOOL_T doingMove; + + switch( action & 0xFF) { case C_START: + DYNARR_RESET(trkSeg_t,anchors_da); if (selectedTrackCount == 0) { ErrorMessage( MSG_NO_SELECTED_TRK ); return C_TERMINATE; @@ -1197,63 +1712,123 @@ static STATUS_T CmdMove( } InfoMessage( _("Drag to move selected tracks - Shift+Ctrl+Arrow micro-steps the move") ); state = 0; + ep1 = -1; + ep2 = -1; + doingMove = FALSE; + break; + + case wActionMove: + DYNARR_RESET(trkSeg_t,anchors_da); + CreateMoveAnchor(pos); break; case C_DOWN: + DYNARR_RESET(trkSeg_t,anchors_da); + if (doingMove) { + doingMove = FALSE; + UndoEnd(); + } + if (SelectedTracksAreFrozen()) { return C_TERMINATE; } UndoStart( _("Move Tracks"), "move" ); base = zero; orig = pos; - GetMovedTracks(quickMove != MOVE_QUICK); + + GetMovedTracks(TRUE); SetMoveD( TRUE, base, 0.0 ); - //DrawMovedTracks(); drawCount = 0; state = 1; - MainRedraw(); - MapRedraw(); return C_CONTINUE; case C_MOVE: + DYNARR_RESET(trkSeg_t,anchors_da); + ep1=-1; + ep2=-1; drawEnable = enableMoveDraw; - //DrawMovedTracks(); base.x = pos.x - orig.x; base.y = pos.y - orig.y; SnapPos( &base ); SetMoveD( TRUE, base, 0.0 ); - //DrawMovedTracks(); + if (((MyGetKeyState()&(WKEY_ALT)) == 0) == magneticSnap) { // ALT + if (FindEndIntersection(base,zero,0.0,&t1,&ep1,&t2,&ep2)) { + coOrd pos2 = GetTrkEndPos(t2,ep2); + pos2.x +=base.x; + pos2.y +=base.y; + CreateEndAnchor(pos2,FALSE); + CreateEndAnchor(GetTrkEndPos(t1,ep1),TRUE); + } + } #ifdef DRAWCOUNT InfoMessage( " [%s %s] #%ld", FormatDistance(base.x), FormatDistance(base.y), drawCount ); #else InfoMessage( " [%s %s]", FormatDistance(base.x), FormatDistance(base.y) ); #endif drawEnable = TRUE; - MainRedraw(); - MapRedraw(); return C_CONTINUE; case C_UP: + DYNARR_RESET(trkSeg_t,anchors_da); state = 0; - //DrawMovedTracks(); FreeTempStrings(); - MoveTracks( quickMove==MOVE_QUICK, TRUE, FALSE, base, zero, 0.0 ); + if (t1 && ep1>=0 && t2 && ep2>=0) { + MoveToJoin(t2,ep2,t1,ep1); + } else { + MoveTracks( FALSE, TRUE, FALSE, base, zero, 0.0, TRUE ); + } + ep1 = -1; + ep2 = -1; + tlist_da.cnt = 0; return C_TERMINATE; case C_CMDMENU: - wMenuPopupShow( selectPopup1M ); - return C_CONTINUE; - - case C_REDRAW: - /* DO_REDRAW */ - if ( state == 0 ) - break; - DrawSelectedTracksD( &mainD, wDrawColorWhite ); + if (doingMove) UndoEnd(); + doingMove = FALSE; + base = pos; + track_p trk = OnTrack(&pos, FALSE, FALSE); //Note pollutes pos if turntable + if ((trk) && + QueryTrack(trk,Q_CAN_ADD_ENDPOINTS)) { //Turntable snap to center if within 1/4 radius + trackParams_t trackParams; + if (GetTrackParams(PARAMS_CORNU, trk, pos, &trackParams)) { + DIST_T dist = FindDistance(base, trackParams.ttcenter); + if (dist < trackParams.ttradius/4) { + cmdMenuPos = trackParams.ttcenter; + } + } + } + moveDescPos = pos; + moveDescTrk = trk; + SetUpMenu2(pos,trk); + menuPos = pos; + wMenuPopupShow( selectPopup2M ); + return C_CONTINUE; + + case C_TEXT: + if ((action>>8) == 'c') { + panCenter = pos; + LOG( log_pan, 2, ( "PanCenter:Sel-%d %0.3f %0.3f\n", __LINE__, panCenter.x, panCenter.y ) ); + PanHere((void*)0); + } + if ((action>>8) == 'e') { + DoZoomExtents(0); + } + if ((action>>8) == '0' || (action>>8 == 'o')) { + PanMenuEnter('o'); + } + break; + case C_REDRAW: + /* DO_REDRAW */ + if (anchors_da.cnt) + DrawSegs( &tempD, zero, 0.0, &anchors(0), anchors_da.cnt, trackGauge, wDrawColorBlack ); + if ( state == 0 ) + break; DrawMovedTracks(); + break; case wActionExtKey: if (state) return C_CONTINUE; if (SelectedTracksAreFrozen()) return C_TERMINATE; if ((MyGetKeyState() & - (WKEY_SHIFT | WKEY_CTRL)) == (WKEY_SHIFT | WKEY_CTRL)) { + (WKEY_SHIFT | WKEY_CTRL)) == (WKEY_SHIFT | WKEY_CTRL)) { //Both base = zero; DIST_T w = tempD.scale/tempD.dpi; switch((wAccelKey_e) action>>8) { @@ -1275,21 +1850,35 @@ static STATUS_T CmdMove( } drawEnable = enableMoveDraw; - GetMovedTracks(quickMove!=MOVE_QUICK); - UndoStart( _("Move Tracks"), "move" ); + GetMovedTracks(TRUE); + if (!doingMove) UndoStart( _("Move Tracks"), "move" ); + doingMove = TRUE; SetMoveD( TRUE, base, 0.0 ); - DrawSelectedTracksD( &mainD, wDrawColorWhite ); - MoveTracks( quickMove==MOVE_QUICK, TRUE, FALSE, base, zero, 0.0 ); + MoveTracks( FALSE, TRUE, FALSE, base, zero, 0.0, FALSE ); ++microCount; if (microCount>5) { microCount = 0; - MainRedraw(); - MapRedraw(); + MainRedraw(); // Micro step move } return C_CONTINUE; } break; + case C_FINISH: + if (doingMove) { + doingMove = FALSE; + UndoEnd(); + } + tlist_da.cnt = 0; + break; + case C_CONFIRM: + case C_CANCEL: + if (doingMove) { + doingMove = FALSE; + UndoUndo(); + } + tlist_da.cnt = 0; + break; default: break; } @@ -1297,13 +1886,18 @@ static STATUS_T CmdMove( } -wMenuPush_p rotateAlignMI; -int rotateAlignState = 0; -static void RotateAlign( void ) +static int rotateAlignState = 0; + +static void RotateAlign( BOOL_T align ) { - rotateAlignState = 1; - InfoMessage( _("Click on selected object to align") ); + rotateAlignState = 0; + if (align) { + rotateAlignState = 1; + doingAlign = TRUE; + mode = MOVE; + InfoMessage( _("Align: Click on a selected object to be aligned") ); + } } static STATUS_T CmdRotate( @@ -1311,18 +1905,27 @@ static STATUS_T CmdRotate( coOrd pos ) { static coOrd base; + static coOrd orig_base; static coOrd orig; static ANGLE_T angle; static BOOL_T drawnAngle; static ANGLE_T baseAngle; + static BOOL_T clockwise; + static BOOL_T direction_set; static track_p trk; ANGLE_T angle1; coOrd pos1; static int state; + static EPINX_T ep1; + static EPINX_T ep2; + static track_p t1; + static track_p t2; + switch( action ) { case C_START: + DYNARR_RESET(trkSeg_t,anchors_da); state = 0; if (selectedTrackCount == 0) { ErrorMessage( MSG_NO_SELECTED_TRK ); @@ -1334,8 +1937,15 @@ static STATUS_T CmdRotate( InfoMessage( _("Drag to rotate selected tracks, Shift+RightClick for QuickRotate Menu") ); wMenuPushEnable( rotateAlignMI, TRUE ); rotateAlignState = 0; + ep1 = -1; + ep2 = -1; + break; + case wActionMove: + DYNARR_RESET(trkSeg_t,anchors_da); + CreateRotateAnchor(pos); break; case C_DOWN: + DYNARR_RESET(trkSeg_t,anchors_da); state = 1; if (SelectedTracksAreFrozen()) { return C_TERMINATE; @@ -1357,12 +1967,15 @@ static STATUS_T CmdRotate( } } } - GetMovedTracks(FALSE); + CreateRotateAnchor(orig); + GetMovedTracks(TRUE); SetMoveD( FALSE, base, angle ); + /*DrawLine( &mainD, base, orig, 0, wDrawColorBlack ); DrawMovedTracks(FALSE, orig, angle);*/ } else { pos1 = pos; + drawnAngle = FALSE; onTrackInSplit = TRUE; trk = OnTrack( &pos, TRUE, FALSE ); onTrackInSplit = FALSE; @@ -1396,13 +2009,13 @@ static STATUS_T CmdRotate( } GetMovedTracks(TRUE); SetMoveD( FALSE, orig, angle ); - //DrawMovedTracks(); } } - MainRedraw(); - MapRedraw(); return C_CONTINUE; case C_MOVE: + DYNARR_RESET(trkSeg_t,anchors_da); + ep1=-1; + ep2=-1; if ( rotateAlignState == 1 ) return C_CONTINUE; if ( rotateAlignState == 2 ) { @@ -1416,7 +2029,6 @@ static STATUS_T CmdRotate( ErrorMessage( MSG_2ND_TRACK_MUST_BE_UNSELECTED ); return C_CONTINUE; } - //DrawMovedTracks(); angle1 = NormalizeAngle( GetAngleAtPoint( trk, pos, NULL, NULL ) ); angle = NormalizeAngle(angle1-baseAngle); if ( angle > 90 && angle < 270 ) @@ -1427,65 +2039,95 @@ static STATUS_T CmdRotate( InfoMessage( _("Angle %0.3f"), angle1 ); SetMoveD( FALSE, orig, angle ); /*printf( "angle 2 = %0.3f\n", angle );*/ - //DrawMovedTracks(); - MainRedraw(); - MapRedraw(); return C_CONTINUE; } - if ( FindDistance( orig, pos ) > (6.0/75.0)*mainD.scale ) { - drawEnable = enableMoveDraw; - if (drawnAngle) { - DrawLine( &tempD, base, orig, 0, wDrawColorBlack ); - DrawMovedTracks(); - } else if (quickMove != MOVE_QUICK) { - DrawSelectedTracksD( &mainD, wDrawColorWhite ); - } + ANGLE_T diff_angle = 0.0; + base = pos; + drawEnable = enableMoveDraw; + if ( FindDistance( orig, pos ) > (20.0/75.0)*mainD.scale ) { + ANGLE_T old_angle = angle; angle = FindAngle( orig, pos ); if (!drawnAngle) { baseAngle = angle; drawnAngle = TRUE; + direction_set = FALSE; + } else { + if (!direction_set) { + if (DifferenceBetweenAngles(baseAngle,angle)>=0) clockwise = TRUE; + else clockwise = FALSE; + direction_set = TRUE; + } else { + if (clockwise) { + if (DifferenceBetweenAngles(baseAngle,angle)<0 && fabs(DifferenceBetweenAngles(baseAngle, old_angle))<5) + clockwise = FALSE; + } else { + if (DifferenceBetweenAngles(baseAngle,angle)>=0 && fabs(DifferenceBetweenAngles(baseAngle,old_angle))<5) + clockwise = TRUE; + } + } + } + orig_base = base = pos; + //angle = NormalizeAngle( angle-baseAngle ); + diff_angle = DifferenceBetweenAngles(baseAngle,angle); + if ( (MyGetKeyState() & (WKEY_CTRL|WKEY_SHIFT)) == (WKEY_CTRL|WKEY_SHIFT) ) { //Both Shift+Ctrl + if (clockwise) { + if (diff_angle<0) diff_angle+=360; + } else { + if (diff_angle>0) diff_angle-=360; + } + diff_angle = floor((diff_angle+7.5)/15.0)*15.0; + angle = baseAngle+diff_angle; } - base = pos; - angle = NormalizeAngle( angle-baseAngle ); - if ( MyGetKeyState()&WKEY_CTRL ) { - angle = NormalizeAngle(floor((angle+7.5)/15.0)*15.0); - Translate( &base, orig, angle+baseAngle, FindDistance(orig,pos) ); + Translate( &base, orig, angle, FindDistance(orig,pos) ); //Line one + Translate( &orig_base,orig, baseAngle, FindDistance(orig,pos)<=(60.0/75.00*mainD.scale)?FindDistance(orig,pos):60.0/75.00*mainD.scale ); //Line two + SetMoveD( FALSE, orig, NormalizeAngle( angle-baseAngle ) ); + if (((MyGetKeyState()&(WKEY_ALT)) == WKEY_ALT) != magneticSnap) { //Just Shift + if (FindEndIntersection(zero,orig,NormalizeAngle( angle-baseAngle ),&t1,&ep1,&t2,&ep2)) { + coOrd pos2 = GetTrkEndPos(t2,ep2); + coOrd pos1 = GetTrkEndPos(t1,ep1); + Rotate(&pos2,orig,NormalizeAngle( angle-baseAngle )); + CreateEndAnchor(pos2,FALSE); + CreateEndAnchor(pos1,TRUE); + } } - DrawLine( &tempD, base, orig, 0, wDrawColorBlack ); - SetMoveD( FALSE, orig, angle ); - //DrawMovedTracks(); + #ifdef DRAWCOUNT - InfoMessage( _(" Angle %0.3f #%ld"), angle, drawCount ); + InfoMessage( _("Angle %0.3f #%ld"), fabs(diff_angle), drawCount ); #else - InfoMessage( _(" Angle %0.3f"), angle ); + InfoMessage( _("Angle %0.3f %s"), fabs(diff_angle), clockwise?"Clockwise":"Counter-Clockwise" ); #endif wFlush(); drawEnable = TRUE; - } - MainRedraw(); - MapRedraw(); + } else + InfoMessage( _("Origin Set. Drag away to set start angle")); + return C_CONTINUE; + case C_UP: + DYNARR_RESET(trkSeg_t,anchors_da); state = 0; - if ( rotateAlignState == 1 ) { - if ( trk && GetTrkSelected(trk) ) { - InfoMessage( _("Click on the 2nd Unselected object") ); - rotateAlignState = 2; - } - return C_CONTINUE; - } - FreeTempStrings(); - if ( rotateAlignState == 2 ) { - //DrawMovedTracks(); - MoveTracks( quickMove==MOVE_QUICK, FALSE, TRUE, zero, orig, angle ); + if (t1 && ep1>=0 && t2 && ep2>=0) { + MoveToJoin(t2,ep2,t1,ep1); + CleanSegs(&tempSegs_da); rotateAlignState = 0; - } else if (drawnAngle) { - DrawLine( &tempD, base, orig, 0, wDrawColorBlack ); - //DrawMovedTracks(); - MoveTracks( quickMove==MOVE_QUICK, FALSE, TRUE, zero, orig, angle ); + } else { + if ( rotateAlignState == 1 ) { + if ( trk && GetTrkSelected(trk) ) { + InfoMessage( _("Align: Click on the 2nd unselected object") ); + rotateAlignState = 2; + } + return C_CONTINUE; + } + CleanSegs(&tempSegs_da); + if ( rotateAlignState == 2 ) { + MoveTracks( FALSE, FALSE, TRUE, zero, orig, angle, TRUE ); + rotateAlignState = 0; + } else if (drawnAngle) { + MoveTracks( FALSE, FALSE, TRUE, zero, orig, NormalizeAngle( angle-baseAngle ), TRUE ); + } } - MainRedraw(); - MapRedraw(); + UndoEnd(); + tlist_da.cnt = 0; return C_TERMINATE; case C_CMDMENU: @@ -1501,16 +2143,65 @@ static STATUS_T CmdRotate( } } } + moveDescPos = pos; + moveDescTrk = trk; + SetUpMenu2(pos,trk); + menuPos = pos; wMenuPopupShow( selectPopup2M ); return C_CONTINUE; + case C_TEXT: + if ((action>>8) == 'd') { + panCenter = pos; + LOG( log_pan, 2, ( "PanCenter:Sel-%d %0.3f %0.3f\n", __LINE__, panCenter.x, panCenter.y ) ); + PanHere((void*)0); + } + if ((action>>8) == 'e') { + DoZoomExtents(0); + } + if ((action>>8) == '0' || (action>>8 == 'o')) { + PanMenuEnter('o'); + } + break; case C_REDRAW: + if (anchors_da.cnt) + DrawSegs( &tempD, zero, 0.0, &anchors(0), anchors_da.cnt, trackGauge, wDrawColorBlack ); /* DO_REDRAW */ if ( state == 0 ) break; - if ( rotateAlignState != 2 ) - DrawLine( &tempD, base, orig, 0, wDrawColorBlack ); - DrawSelectedTracksD( &mainD, wDrawColorWhite ); + if ( rotateAlignState != 2 ) { + DIST_T width = mainD.scale*0.5; + DrawLine( &tempD, base, orig, 0, wDrawColorBlue ); + if (drawnAngle) { + DrawLine( &tempD, orig_base, orig, (wDrawWidth)width, wDrawColorBlue ); + ANGLE_T a = DifferenceBetweenAngles(FindAngle(orig, orig_base),FindAngle(orig, base)); + + DIST_T dist = FindDistance(orig,base); + if (dist>(60.0/75.0)*mainD.scale) dist = (60.0/75.0)*mainD.scale; + + if (direction_set) { + if (clockwise) { + if (a<0) a = a + 360; + DrawArc( &tempD, orig, dist/2, FindAngle(orig,orig_base), a, FALSE, 0, wDrawColorBlue); + } else { + if (a>0) a = a - 360; + DrawArc( &tempD, orig, dist/2, FindAngle(orig,base), fabs(a), FALSE, 0, wDrawColorBlue); + } + DIST_T d; + d = mainD.scale*0.25; + ANGLE_T arrow_a = NormalizeAngle(FindAngle(orig,orig_base)+a/2); + coOrd arr1,arr2,arr3; + Translate(&arr2,orig,arrow_a,dist/2); + if (clockwise) arrow_a +=90; + else arrow_a -=90; + Translate(&arr1,arr2,arrow_a+135,d/2); + Translate(&arr3,arr2,arrow_a-135,d/2); + DrawLine( &tempD, arr1, arr2, 0, wDrawColorBlue ); + DrawLine( &tempD, arr2, arr3, 0, wDrawColorBlue ); + } + } + + } DrawMovedTracks(); break; @@ -1524,12 +2215,9 @@ static void QuickMove( void* pos) { return; wDrawDelayUpdate( mainD.d, TRUE ); GetMovedTracks(FALSE); - DrawSelectedTracksD( &mainD, wDrawColorWhite ); UndoStart( _("Move Tracks"), "Move Tracks" ); - MoveTracks( quickMove==MOVE_QUICK, TRUE, FALSE, move_pos, zero, 0.0 ); + MoveTracks( TRUE, TRUE, FALSE, move_pos, zero, 0.0, TRUE ); wDrawDelayUpdate( mainD.d, FALSE ); - MainRedraw(); - MapRedraw(); } static void QuickRotate( void* pangle ) @@ -1539,18 +2227,16 @@ static void QuickRotate( void* pangle ) return; wDrawDelayUpdate( mainD.d, TRUE ); GetMovedTracks(FALSE); - DrawSelectedTracksD( &mainD, wDrawColorWhite ); + //DrawSelectedTracksD( &mainD, wDrawColorWhite ); UndoStart( _("Rotate Tracks"), "Rotate Tracks" ); - MoveTracks( quickMove==MOVE_QUICK, FALSE, TRUE, zero, cmdMenuPos, angle ); + MoveTracks( TRUE, FALSE, TRUE, zero, cmdMenuPos, (double)angle/1000, TRUE); wDrawDelayUpdate( mainD.d, FALSE ); - MainRedraw(); - MapRedraw(); } static wMenu_p moveDescM; static wMenuToggle_p moveDescMI; -static track_p moveDescTrk; + static void ChangeDescFlag( wBool_t set, void * mode ) { wDrawDelayUpdate( mainD.d, TRUE ); @@ -1565,113 +2251,228 @@ static void ChangeDescFlag( wBool_t set, void * mode ) wDrawDelayUpdate( mainD.d, FALSE ); } -STATUS_T CmdMoveDescription( - wAction_t action, - coOrd pos ) -{ - static track_p trk; - static EPINX_T ep; - track_p trk1; - EPINX_T ep1; - DIST_T d, dd; - static int mode; - - switch (action) { - case C_START: - if ( labelWhen < 2 || mainD.scale > labelScale || - (labelEnable&(LABELENABLE_TRKDESC|LABELENABLE_LENGTHS|LABELENABLE_ENDPT_ELEV))==0 ) { - ErrorMessage( MSG_DESC_NOT_VISIBLE ); - return C_TERMINATE; - } - InfoMessage( _("Select and drag a description") ); - break; - case C_DOWN: - if ( labelWhen < 2 || mainD.scale > labelScale ) - return C_TERMINATE; - trk = NULL; - dd = 10000; - trk1 = NULL; +track_p FindTrackDescription(coOrd pos, EPINX_T * ep_o, int * mode_o, BOOL_T show_hidden, BOOL_T * hidden_o) { + track_p trk = NULL; + DIST_T d, dd = 10000; + track_p trk1 = NULL; + EPINX_T ep1=-1, ep=-1; + BOOL_T hidden_t, hidden; + coOrd dpos = pos; + coOrd cpos; + int mode = -1; while ( TrackIterate( &trk1 ) ) { if ( !GetLayerVisible(GetTrkLayer(trk1)) ) continue; if ( (!GetTrkVisible(trk1)) && drawTunnel==0 ) continue; - for ( ep1=0; ep1