diff options
Diffstat (limited to 'app/bin/cpull.c')
-rw-r--r-- | app/bin/cpull.c | 263 |
1 files changed, 200 insertions, 63 deletions
diff --git a/app/bin/cpull.c b/app/bin/cpull.c index d7f7c80..7f27864 100644 --- a/app/bin/cpull.c +++ b/app/bin/cpull.c @@ -60,6 +60,9 @@ static dynArr_t section_da; #define section(N) DYNARR_N( section_t, section_da, N ) static double contribL, contribR; +static dynArr_t anchors_da; +#define anchors(N) DYNARR_N(trkSeg_t,anchors_da,N) + typedef enum { freeEnd, connectedEnd, loopEnd } ending_e; @@ -452,12 +455,15 @@ static void PullTracks( int cnt1, cnt2; int rc; - if (QueryTrack(trk1,Q_CAN_ADD_ENDPOINTS) || QueryTrack(trk2,Q_CAN_ADD_ENDPOINTS)) { + if (QueryTrack(trk1,Q_CAN_ADD_ENDPOINTS)) { ConnectTurntableTracks(trk1, ep1, trk2, ep2 ); return; + } else if (QueryTrack(trk2,Q_CAN_ADD_ENDPOINTS)) { + ConnectTurntableTracks(trk2, ep2, trk1, ep1 ); + return; } - if (ep1<0 || ep1<0 ) return; + if (ep1<0 || ep2<0 ) return; if (ConnectAbuttingTracks( trk1, ep1, trk2, ep2 )) return; @@ -589,57 +595,202 @@ printf("T%d [%0.3f %0.3f %0.3f]\n", GetTrkIndex(trk1), p1.x, p1.y, a1 ); InfoMessage( _("%d tracks moved"), cnt ); } +static void CreateConnectAnchor(EPINX_T ep, track_p t, BOOL_T shift) { + coOrd pos = GetTrkEndPos(t,ep); + DIST_T d = tempD.scale*0.15; + DIST_T w = tempD.scale/tempD.dpi*4; + ANGLE_T a = GetTrkEndAngle(t,ep); + int i; + if (!shift) { + DYNARR_APPEND(trkSeg_t,anchors_da,1); + i = anchors_da.cnt-1; + anchors(i).type = SEG_STRLIN; + anchors(i).color = wDrawColorBlue; + anchors(i).u.l.pos[0] = pos; + Translate(&anchors(i).u.l.pos[1],pos,a+90,-GetTrkGauge(t)); + Translate(&anchors(i).u.l.pos[1],anchors(i).u.l.pos[1],a,-d); + anchors(i).width = w; + DYNARR_APPEND(trkSeg_t,anchors_da,1); + i = anchors_da.cnt-1; + anchors(i).type = SEG_STRLIN; + anchors(i).color = wDrawColorBlue; + anchors(i).u.l.pos[0] = pos; + Translate(&anchors(i).u.l.pos[1],pos,a+90,GetTrkGauge(t)); + Translate(&anchors(i).u.l.pos[1],anchors(i).u.l.pos[1],a,-d); + anchors(i).width = w; + } else { + DYNARR_APPEND(trkSeg_t,anchors_da,1); + i = anchors_da.cnt-1; + anchors(i).type = SEG_STRLIN; + anchors(i).color = wDrawColorBlue; + Translate(&anchors(i).u.l.pos[0],pos,a+90,GetTrkGauge(t)); + Translate(&anchors(i).u.l.pos[0],anchors(i).u.l.pos[0],a,d); + Translate(&anchors(i).u.l.pos[1],pos,a+90,-GetTrkGauge(t)); + Translate(&anchors(i).u.l.pos[1],anchors(i).u.l.pos[1],a,-d); + anchors(i).width = w; + DYNARR_APPEND(trkSeg_t,anchors_da,1); + i = anchors_da.cnt-1; + anchors(i).type = SEG_STRLIN; + anchors(i).color = wDrawColorBlue; + Translate(&anchors(i).u.l.pos[0],pos,a+90,GetTrkGauge(t)); + Translate(&anchors(i).u.l.pos[0],anchors(i).u.l.pos[0],a,-d); + Translate(&anchors(i).u.l.pos[1],pos,a+90,-GetTrkGauge(t)); + Translate(&anchors(i).u.l.pos[1],anchors(i).u.l.pos[1],a,d); + anchors(i).width = w; + } +} + +STATUS_T ConnectMultiple() { + int countTracksR0 =0,countTracksR1 =0, possibleEndPoints =0; + if (selectedTrackCount==0) { + ErrorMessage(_("Connect Multiple Tracks - Select multiple tracks to join first")); + return C_CONTINUE; + } + if (NoticeMessage(_("Try to Connect all Selected Tracks?"), _("Yes"), _("No"))<=0) return C_CONTINUE; + track_p trk1 = NULL; + track_p trk2 = NULL; + EPINX_T ep1,ep2; + ANGLE_T a; + DIST_T d; + UndoStart( _("ReConnect"),"Try to reconnect all selected tracks"); + for (int i=0;i<2;i++) { // Try twice - in case later joins help earlier ones and to try close ones first + while ( TrackIterate( &trk1 ) ) { + BOOL_T found = FALSE; + if ( GetTrkSelected( trk1 ) ) { + for (ep1=0; ep1<GetTrkEndPtCnt(trk1); ep1++) { + if (!GetTrkEndTrk( trk1, ep1 )) { + trk2 = NULL; + while (!found && TrackIterate(&trk2) ) { + if (trk1 == trk2) continue; + for (ep2=0; ep2<GetTrkEndPtCnt(trk2); ep2++) { + if (GetTrkEndTrk( trk2, ep2 )) continue; + d = FindDistance(GetTrkEndPos(trk1,ep1),GetTrkEndPos(trk2,ep2)); + a = NormalizeAngle( 180+GetTrkEndAngle( trk1, ep1 ) - GetTrkEndAngle( trk2, ep2 )+(connectAngle/2.0)); + // Take two passes. In round one favor closer connections. In round two try anything. + if ( (i==0 && (d < connectDistance) && (a < connectAngle)) || + (i>0 && (d<3.0 && a<7.5))) { // Match PullTracks criteria in round 2 + PullTracks(trk1,ep1,trk2,ep2); + if (GetTrkEndTrk( trk2, ep2 )) { + found = TRUE; + if (i==0) + countTracksR0++; + else + countTracksR1++; + break; //Stop looking + } else if (i==1) possibleEndPoints++; + } + } + } + if (found) break; //Next EndPoint + } + } + } + } + } + UndoEnd(); + NoticeMessage(_("Round 1 %d and Round 2 %d tracks connected, %d close pairs of end Points were not connected"), _("Ok"), NULL, countTracksR0, countTracksR1, possibleEndPoints); + return C_TERMINATE; +} + +static wMenu_p pullPopupM; static STATUS_T CmdPull( wAction_t action, coOrd pos ) { - static track_p trk1; - static EPINX_T ep1; + static track_p trk1, t1, t2; + static BOOL_T t_turn1, t_turn2; + static EPINX_T ep1, t_ep1, t_ep2; track_p trk2; EPINX_T ep2; static BOOL_T turntable; int countTracksR0 = 0, countTracksR1 = 0, possibleEndPoints = 0; BOOL_T found = FALSE; - ANGLE_T a; - DIST_T d; - switch (action) { + switch (action&0xFF) { case C_START: if (selectedTrackCount==0) - InfoMessage( _("Select first end-point to connect") ); + InfoMessage( _("Select first endpoint or turntable to connect, +Shift to tighten") ); else - InfoMessage( _("Select first end-point to connect, or Right-Click for connecting selected tracks") ); + InfoMessage( _("Select first endpoint to connect, or Right-Click for connecting selected tracks (not turntable)") ); trk1 = NULL; turntable = FALSE; + t1 = t2 = NULL; + t_turn1 = t_turn2 = FALSE; return C_CONTINUE; + case wActionMove: + DYNARR_RESET(trkSeg_t,anchors_da); + if ((MyGetKeyState() & WKEY_SHIFT) == 0 ) { + if (trk1 == NULL) { + if ((t1= OnTrack( &pos, FALSE, TRUE )) != NULL) { + if ((t_ep1 = PickUnconnectedEndPointSilent( pos, t1 )) < 0) { + if (QueryTrack(t1, Q_CAN_ADD_ENDPOINTS)) { + DrawTrack(t1,&mainD,wDrawColorBlue); + t_turn1 = TRUE; + } else t1 = NULL; + } + if (t1 && t_ep1 >=0) + CreateConnectAnchor(t_ep1,t1,FALSE); + } + } else { + if (t1 != NULL) { + if (t_turn1) DrawTrack(t1,&mainD,wDrawColorBlue); + else CreateConnectAnchor(t_ep1,t1,FALSE); + } + if ((t2= OnTrackIgnore( &pos, FALSE, TRUE, t1 )) != NULL) { + if ((t_ep2 = PickUnconnectedEndPointSilent( pos, t2 )) < 0) { + if (QueryTrack(t2, Q_CAN_ADD_ENDPOINTS)) { + DrawTrack(t2,&mainD,wDrawColorBlue); + t_turn2 = TRUE; + } else t2 = NULL; + } + if (t2 && t_ep2 >=0) + CreateConnectAnchor(t_ep2,t2,FALSE); + } + + } + } else { //Shift, tighten + t1 = OnTrack( &pos, FALSE, TRUE ); + if (t1 == NULL) + return C_CONTINUE; + t_ep1 = PickUnconnectedEndPointSilent( pos, t1 ); + if ( t_ep1 < 0 ) + return C_CONTINUE; + CreateConnectAnchor(t_ep1,t1,TRUE); + } + break; + case C_LCLICK: - if ( (MyGetKeyState() & WKEY_SHIFT) == 0 ) { + if ( (MyGetKeyState() & WKEY_SHIFT) == 0 ) { //No shift - try and join if (trk1 == NULL) { - if ((trk1 = OnTrack( &pos, TRUE, FALSE )) != NULL) { + if ((trk1 = OnTrack( &pos, TRUE, TRUE )) != NULL) { if ((ep1 = PickUnconnectedEndPoint( pos, trk1 )) < 0) { if (QueryTrack(trk1, Q_CAN_ADD_ENDPOINTS)) { turntable = TRUE; ep1 = -1; } else trk1 = NULL; } else { - InfoMessage( _("Select second end-point to connect") ); + InfoMessage( _("Select second endpoint or turntable to connect") ); } } } else { - if ((trk2 = OnTrack( &pos, TRUE, FALSE )) != NULL) { + if ((trk2 = OnTrackIgnore( &pos, TRUE, TRUE, trk1 )) != NULL) { + if (trk2 == trk1) { + InfoMessage( _("Same Track! - please select another") ); + return C_CONTINUE; + } if ((ep2 = PickUnconnectedEndPoint( pos, trk2 )) >= 0 ) { PullTracks( trk1, ep1, trk2, ep2 ); trk1 = NULL; inError = TRUE; return C_TERMINATE; } - if (!turntable && QueryTrack(trk2, Q_CAN_ADD_ENDPOINTS)) { + if (!turntable && QueryTrack(trk2, Q_CAN_ADD_ENDPOINTS)) { /*Second end a turntable */ ep2 = -1; turntable = TRUE; PullTracks( trk2, ep2, trk1, ep1); @@ -651,7 +802,7 @@ static STATUS_T CmdPull( } } } else { - trk1 = OnTrack( &pos, TRUE, FALSE ); + trk1 = OnTrack( &pos, TRUE, TRUE ); if (trk1 == NULL) return C_CONTINUE; ep1 = PickUnconnectedEndPoint( pos, trk1 ); @@ -664,56 +815,23 @@ static STATUS_T CmdPull( } return C_CONTINUE; - case C_RCLICK: - if (selectedTrackCount==0) { - ErrorMessage(_("Connect Multiple Tracks - Select multiple tracks to join first")); - return C_CONTINUE; - } - if (NoticeMessage(_("Try to Connect all Selected Tracks?"), _("Yes"), _("No"))<=0) return C_CONTINUE; - trk1 = NULL; - trk2 = NULL; - UndoStart( _("ReConnect"),"Try to reconnect all selected tracks"); - for (int i=0;i<2;i++) { // Try twice - in case later joins help earlier ones and to try close ones first - while ( TrackIterate( &trk1 ) ) { - found = FALSE; - if ( GetTrkSelected( trk1 ) ) { - for (ep1=0; ep1<GetTrkEndPtCnt(trk1); ep1++) { - if (!GetTrkEndTrk( trk1, ep1 )) { - trk2 = NULL; - while (!found && TrackIterate(&trk2) ) { - if (trk1 == trk2) continue; - for (ep2=0; ep2<GetTrkEndPtCnt(trk2); ep2++) { - if (GetTrkEndTrk( trk2, ep2 )) continue; - d = FindDistance(GetTrkEndPos(trk1,ep1),GetTrkEndPos(trk2,ep2)); - a = NormalizeAngle( 180+GetTrkEndAngle( trk1, ep1 ) - GetTrkEndAngle( trk2, ep2 )+(connectAngle/2.0)); - // Take two passes. In round one favor closer connections. In round two try anything. - if ( (i==0 && (d < connectDistance) && (a < connectAngle)) || - (i>0 && (d<3.0 && a<7.5))) { // Match PullTracks criteria in round 2 - PullTracks(trk1,ep1,trk2,ep2); - if (GetTrkEndTrk( trk2, ep2 )) { - found = TRUE; - if (i==0) - countTracksR0++; - else - countTracksR1++; - break; //Stop looking - } else if (i==1) possibleEndPoints++; - } - } - } - if (found) break; //Next EndPoint - } - } - } - } - } - UndoEnd(); - NoticeMessage(_("Round 1 %d and Round 2 %d tracks connected, %d close pairs of end Points were not connected"), _("Ok"), NULL, countTracksR0, countTracksR1, possibleEndPoints); - return C_TERMINATE; - case C_REDRAW: + if (anchors_da.cnt) + DrawSegs( &tempD, zero, 0.0, &anchors(0), anchors_da.cnt, trackGauge, wDrawColorBlack ); + if (t1 && t_turn1) + DrawTrack(t1,&tempD,wDrawColorBlue); + if (t2 && t_turn2) + DrawTrack(t2,&tempD,wDrawColorBlue); return C_CONTINUE; + case C_TEXT: + if (action>>8 == 'S') { + wBool_t rc = ConnectMultiple(); + MainRedraw(); // CmdPull: ConnectMultiple + return rc; + } + break; + case C_CANCEL: return C_TERMINATE; @@ -723,16 +841,35 @@ static STATUS_T CmdPull( case C_CONFIRM: return C_CONTINUE; + case C_CMDMENU: + menuPos = pos; + wMenuPopupShow( pullPopupM ); + return C_CONTINUE; + break; + + default: return C_CONTINUE; } + return C_CONTINUE; } #include "bitmaps/pull.xpm" +wMenuPush_p pullConnectMultiple; + +void pullMenuEnter(int key) { + int action; + action = C_TEXT; + action |= key<<8; + CmdPull(action,zero); +} + void InitCmdPull( wMenu_p menu ) { - AddMenuButton( menu, CmdPull, "cmdConnect", _("Connect Two Tracks"), wIconCreatePixMap(pull_xpm), LEVEL0_50, IC_STICKY|IC_LCLICK|IC_POPUP2|IC_RCLICK, ACCL_CONNECT, NULL ); + AddMenuButton( menu, CmdPull, "cmdConnect", _("Connect Two Tracks"), wIconCreatePixMap(pull_xpm), LEVEL0_50, IC_STICKY|IC_INITNOTSTICKY|IC_LCLICK|IC_POPUP3|IC_CMDMENU|IC_WANT_MOVE, ACCL_CONNECT, NULL ); + pullPopupM = MenuRegister( "Connect Options" ); + pullConnectMultiple = wMenuPushCreate( pullPopupM, "", _("Connect All Selected - 'S'"), 0, (wMenuCallBack_p)pullMenuEnter, (void*) 'S'); } |