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');  }  | 
