summaryrefslogtreecommitdiff
path: root/app/bin/csplit.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/csplit.c')
-rw-r--r--app/bin/csplit.c293
1 files changed, 269 insertions, 24 deletions
diff --git a/app/bin/csplit.c b/app/bin/csplit.c
index c2b516a..49b87ce 100644
--- a/app/bin/csplit.c
+++ b/app/bin/csplit.c
@@ -22,11 +22,11 @@
#include "cundo.h"
#include "compound.h"
-#include "i18n.h"
-#include "messages.h"
+#include "cselect.h"
#include "track.h"
-#include "utility.h"
+#include "draw.h"
#include "fileio.h"
+#include "common-ui.h"
static wMenu_p splitPopupM[2];
static wMenuToggle_p splitPopupMI[2][4];
@@ -36,9 +36,9 @@ static BOOL_T splitTrkFlip;
static dynArr_t anchors_da;
#define anchors(N) DYNARR_N(trkSeg_t,anchors_da,N)
-static void ChangeSplitEPMode( wBool_t set, void * mode )
+static void ChangeSplitEPMode( void * mode )
{
- long imode = (long)mode;
+ long imode = VP2L(mode);
long option;
int inx0, inx;
@@ -59,7 +59,7 @@ static void ChangeSplitEPMode( wBool_t set, void * mode )
DrawEndPt( &mainD, splitTrkTrk[1], splitTrkEP[1], wDrawColorBlack );
}
-static void CreateSplitAnchorAngle(coOrd pos, track_p t, BOOL_T end, ANGLE_T a) {
+static void CreateSplitAnchorAngle(coOrd pos, track_p t, BOOL_T end, ANGLE_T a, BOOL_T trim) {
DIST_T d = tempD.scale*0.1;
DIST_T w = tempD.scale/tempD.dpi*4;
int i;
@@ -68,8 +68,8 @@ static void CreateSplitAnchorAngle(coOrd pos, track_p t, BOOL_T end, ANGLE_T a)
i = anchors_da.cnt-1;
anchors(i).type = SEG_STRLIN;
anchors(i).color = wDrawColorBlue;
- Translate(&anchors(i).u.l.pos[0],pos,a,GetTrkGauge(t));
- Translate(&anchors(i).u.l.pos[1],pos,a,-GetTrkGauge(t));
+ Translate(&anchors(i).u.l.pos[0],pos,a,trim?2*GetTrkGauge(t):GetTrkGauge(t));
+ Translate(&anchors(i).u.l.pos[1],pos,a,trim?2*-GetTrkGauge(t):-GetTrkGauge(t));
anchors(i).width = w;
} else {
DYNARR_APPEND(trkSeg_t,anchors_da,1);
@@ -95,13 +95,34 @@ static void CreateSplitAnchorAngle(coOrd pos, track_p t, BOOL_T end, ANGLE_T a)
static void CreateSplitAnchor(coOrd pos, track_p t, BOOL_T end) {
ANGLE_T a = NormalizeAngle(GetAngleAtPoint(t,pos,NULL,NULL)+90.0);
- CreateSplitAnchorAngle(pos,t,end,a);
+ CreateSplitAnchorAngle(pos,t,end,a,FALSE);
+}
+
+static void CreateTrimAnchorLeg(coOrd pos, ANGLE_T a, track_p t) {
+ DIST_T d = tempD.scale*0.1;
+ DIST_T w = tempD.scale/tempD.dpi*4;
+ DYNARR_APPEND(trkSeg_t,anchors_da,1);
+ int 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,GetTrkGauge(t)*2);
+ anchors(i).width = w;
+
+}
+
+static void CreateTrimAnchor(coOrd pos, track_p t, track_p s, coOrd cursor) {
+ ANGLE_T a = NormalizeAngle(GetAngleAtPoint(s,pos,NULL,NULL));
+ CreateSplitAnchorAngle(pos,t,FALSE,a,TRUE);
+ ANGLE_T aa = FindAngle(pos,cursor);
+ ANGLE_T d = DifferenceBetweenAngles(a,aa);
+ CreateTrimAnchorLeg(pos,a+(d>0?90:-90),t);
}
static STATUS_T CmdSplitTrack( wAction_t action, coOrd pos )
{
track_p trk0, trk1;
- EPINX_T ep0;
+ EPINX_T ep0 = 0;
int oldTrackCount;
int inx, mode, quad;
ANGLE_T angle;
@@ -110,6 +131,7 @@ static STATUS_T CmdSplitTrack( wAction_t action, coOrd pos )
case C_START:
InfoMessage( _("Select track to split") );
DYNARR_RESET(trkSeg_t,anchors_da);
+ SetAllTrackSelect( FALSE );
/* no break */
case C_DOWN:
case C_MOVE:
@@ -117,7 +139,7 @@ static STATUS_T CmdSplitTrack( wAction_t action, coOrd pos )
break;
case C_UP:
onTrackInSplit = TRUE;
- trk0 = OnTrack( &pos, TRUE, TRUE );
+ trk0 = OnTrack( &pos, FALSE, TRUE );
if ( trk0 != NULL) {
if (!CheckTrackLayer( trk0 ) ) {
onTrackInSplit = FALSE;
@@ -127,9 +149,10 @@ static STATUS_T CmdSplitTrack( wAction_t action, coOrd pos )
if (IsClose(FindDistance(GetTrkEndPos(trk0,ep0),pos)) && (GetTrkEndTrk(trk0,ep0)!=NULL)) {
pos = GetTrkEndPos(trk0,ep0);
} else {
- if (!QueryTrack(trk0,Q_MODIFY_CAN_SPLIT)) {
+ if (!IsTrack(trk0) ||
+ !QueryTrack(trk0,Q_MODIFY_CAN_SPLIT)) {
onTrackInSplit = FALSE;
- InfoMessage(_("Can't Split that Track"));
+ InfoMessage(_("Can't Split that Track Object"));
return C_CONTINUE;
}
}
@@ -142,6 +165,21 @@ static STATUS_T CmdSplitTrack( wAction_t action, coOrd pos )
SplitTrack( trk0, pos, ep0, &trk1, FALSE );
UndoEnd();
return C_TERMINATE;
+ } else if ((trk0 = OnTrack( &pos, FALSE, FALSE))!=NULL && CheckTrackLayerSilent( trk0 )) {
+ if (!QueryTrack(trk0,Q_MODIFY_CAN_SPLIT)) {
+ onTrackInSplit = FALSE;
+ InfoMessage(_("Can't Split that Draw Object"));
+ return C_CONTINUE;
+ }
+ onTrackInSplit = FALSE;
+ UndoStart( _("Split Track"), "SplitTrack( T%d[%d] )", GetTrkIndex(trk0), ep0 );
+ oldTrackCount = trackCount;
+ SplitTrack( trk0, pos, ep0, &trk1, FALSE );
+ UndoEnd();
+ return C_TERMINATE;
+ } else {
+ InfoMessage(_("No Track to Split"));
+ wBeep();
}
onTrackInSplit = FALSE;
return C_TERMINATE;
@@ -152,15 +190,15 @@ static STATUS_T CmdSplitTrack( wAction_t action, coOrd pos )
return C_CONTINUE;
if ( splitPopupM[0] == NULL ) {
splitPopupM[0] = MenuRegister( "End Point Mode R-L" );
- splitPopupMI[0][0] = wMenuToggleCreate( splitPopupM[0], "", _("None"), 0, TRUE, ChangeSplitEPMode, (void*)0 );
- splitPopupMI[0][1] = wMenuToggleCreate( splitPopupM[0], "", _("Left"), 0, FALSE, ChangeSplitEPMode, (void*)1 );
- splitPopupMI[0][2] = wMenuToggleCreate( splitPopupM[0], "", _("Right"), 0, FALSE, ChangeSplitEPMode, (void*)2 );
- splitPopupMI[0][3] = wMenuToggleCreate( splitPopupM[0], "", _("Both"), 0, FALSE, ChangeSplitEPMode, (void*)3 );
+ splitPopupMI[0][0] = wMenuToggleCreate( splitPopupM[0], "", _("None"), 0, TRUE, ChangeSplitEPMode, I2VP(0) );
+ splitPopupMI[0][1] = wMenuToggleCreate( splitPopupM[0], "", _("Left"), 0, FALSE, ChangeSplitEPMode, I2VP(1) );
+ splitPopupMI[0][2] = wMenuToggleCreate( splitPopupM[0], "", _("Right"), 0, FALSE, ChangeSplitEPMode, I2VP(2) );
+ splitPopupMI[0][3] = wMenuToggleCreate( splitPopupM[0], "", _("Both"), 0, FALSE, ChangeSplitEPMode, I2VP(3) );
splitPopupM[1] = MenuRegister( "End Point Mode T-B" );
- splitPopupMI[1][0] = wMenuToggleCreate( splitPopupM[1], "", _("None"), 0, TRUE, ChangeSplitEPMode, (void*)0 );
- splitPopupMI[1][1] = wMenuToggleCreate( splitPopupM[1], "", _("Top"), 0, FALSE, ChangeSplitEPMode, (void*)1 );
- splitPopupMI[1][2] = wMenuToggleCreate( splitPopupM[1], "", _("Bottom"), 0, FALSE, ChangeSplitEPMode, (void*)2 );
- splitPopupMI[1][3] = wMenuToggleCreate( splitPopupM[1], "", _("Both"), 0, FALSE, ChangeSplitEPMode, (void*)3 );
+ splitPopupMI[1][0] = wMenuToggleCreate( splitPopupM[1], "", _("None"), 0, TRUE, ChangeSplitEPMode, I2VP(0) );
+ splitPopupMI[1][1] = wMenuToggleCreate( splitPopupM[1], "", _("Top"), 0, FALSE, ChangeSplitEPMode, I2VP(1) );
+ splitPopupMI[1][2] = wMenuToggleCreate( splitPopupM[1], "", _("Bottom"), 0, FALSE, ChangeSplitEPMode, I2VP(2) );
+ splitPopupMI[1][3] = wMenuToggleCreate( splitPopupM[1], "", _("Both"), 0, FALSE, ChangeSplitEPMode, I2VP(3) );
}
splitTrkEP[0] = PickEndPoint( pos, splitTrkTrk[0] );
angle = NormalizeAngle(GetTrkEndAngle( splitTrkTrk[0], splitTrkEP[0] ));
@@ -195,13 +233,15 @@ static STATUS_T CmdSplitTrack( wAction_t action, coOrd pos )
onTrackInSplit = TRUE;
if ((trk0 = OnTrack( &pos, FALSE, TRUE ))!=NULL && CheckTrackLayerSilent( trk0 )) {
ep0 = PickEndPoint( pos, trk0 );
+ if ( ep0 < 0 )
+ break;
if (IsClose(FindDistance(GetTrkEndPos(trk0,ep0),pos)) && (GetTrkEndTrk(trk0,ep0)!=NULL)) {
CreateSplitAnchor(GetTrkEndPos(trk0,ep0),trk0,TRUE);
} else if (QueryTrack(trk0,Q_IS_TURNOUT)) {
if ((MyGetKeyState()&WKEY_SHIFT) != 0 ) {
if (SplitTurnoutCheck(trk0,pos,ep0,NULL,NULL,NULL,TRUE,&pos,&angle)) {
angle = NormalizeAngle(angle+90);
- CreateSplitAnchorAngle(pos,trk0,FALSE,angle);
+ CreateSplitAnchorAngle(pos,trk0,FALSE,angle,FALSE);
}
} else {
CreateSplitAnchor(GetTrkEndPos(trk0,ep0),trk0,TRUE);
@@ -210,6 +250,71 @@ static STATUS_T CmdSplitTrack( wAction_t action, coOrd pos )
} else if (QueryTrack(trk0,Q_MODIFY_CAN_SPLIT)) {
CreateSplitAnchor(pos,trk0,FALSE);
}
+ } else {
+ if ((trk0 = OnTrack( &pos, FALSE, FALSE))!=NULL && CheckTrackLayerSilent( trk0 )) {
+ if (QueryTrack(trk0,Q_MODIFY_CAN_SPLIT)) {
+ CreateSplitAnchor(pos,trk0, FALSE);
+ }
+ }
+ }
+ onTrackInSplit = FALSE;
+
+ break;
+ case C_REDRAW:
+ if (anchors_da.cnt)
+ DrawSegs( &tempD, zero, 0.0, &anchors(0), anchors_da.cnt, trackGauge, wDrawColorBlack );
+ break;
+ }
+
+ return C_CONTINUE;
+}
+
+static STATUS_T CmdSplitDraw( wAction_t action, coOrd pos )
+{
+ track_p trk0, trk1;
+ EPINX_T ep0 = 0;
+ int oldTrackCount;
+
+ switch (action) {
+ case C_START:
+ InfoMessage( _("Select draw to split") );
+ DYNARR_RESET(trkSeg_t,anchors_da);
+ SetAllTrackSelect( FALSE );
+ /* no break */
+ case C_DOWN:
+ case C_MOVE:
+ return C_CONTINUE;
+ break;
+ case C_UP:
+ onTrackInSplit = TRUE;
+ if ((trk0 = OnTrack( &pos, FALSE, FALSE))!=NULL && CheckTrackLayerSilent( trk0 )) {
+ if (IsTrack(trk0)) return C_CONTINUE;
+ if (!QueryTrack(trk0,Q_MODIFY_CAN_SPLIT)) {
+ onTrackInSplit = FALSE;
+ InfoMessage(_("Can't Split that Draw Object"));
+ return C_CONTINUE;
+ }
+ onTrackInSplit = FALSE;
+ UndoStart( _("Split Draw"), "SplitDraw( T%d[%d] )", GetTrkIndex(trk0), ep0 );
+ oldTrackCount = trackCount;
+ SplitTrack( trk0, pos, ep0, &trk1, FALSE );
+ UndoEnd();
+ return C_TERMINATE;
+ } else {
+ InfoMessage(_("No Draw to Split"));
+ wBeep();
+ }
+ onTrackInSplit = FALSE;
+ return C_TERMINATE;
+ break;
+ case wActionMove:
+ DYNARR_RESET(trkSeg_t,anchors_da);
+ onTrackInSplit = TRUE;
+ if ((trk0 = OnTrack( &pos, FALSE, FALSE))!=NULL && CheckTrackLayerSilent( trk0 )) {
+ if (IsTrack(trk0)) break;
+ if (QueryTrack(trk0,Q_MODIFY_CAN_SPLIT)) {
+ CreateSplitAnchor(pos,trk0, FALSE);
+ }
}
onTrackInSplit = FALSE;
break;
@@ -222,13 +327,153 @@ static STATUS_T CmdSplitTrack( wAction_t action, coOrd pos )
return C_CONTINUE;
}
+typedef enum {TRIM_NONE, TRIM_LINE} TrimState_e;
+
+static STATUS_T CmdTrimDraw( wAction_t action, coOrd pos )
+{
+ track_p trk0, trk1, trk2;
+ EPINX_T ep0 = 0;
+ static TrimState_e trimState;
+ static track_p trimLine;
+ static track_p trk;
+ switch (action&0xFF) {
+ case C_START:
+ InfoMessage( _("Select the draw object to Trim to") );
+ DYNARR_RESET(trkSeg_t,anchors_da);
+ trimState = TRIM_NONE;
+ trimLine = NULL;
+ trk = NULL;
+ SetAllTrackSelect( FALSE );
+ /* no break */
+ case C_DOWN:
+ case C_MOVE:
+ return C_CONTINUE;
+ break;
+ case C_UP:
+ if (trimState == TRIM_NONE) {
+ if ((trk0 = OnTrack( &pos, FALSE, FALSE))!=NULL && CheckTrackLayerSilent( trk0 )) {
+ if (IsTrack(trk0)) {
+ InfoMessage(_("Can't Trim with a Track"));
+ return C_CONTINUE;
+ }
+ trimState = TRIM_LINE;
+ trimLine = trk0;
+ InfoMessage( _("Select an intersecting draw object to Trim") );
+ return C_CONTINUE;
+ }
+ else return C_CONTINUE;
+ }
+ if (!trimLine) {
+ InfoMessage(_("No Draw to Trim with"));
+ wBeep();
+ return C_TERMINATE;
+ }
+ coOrd pos1 = pos;
+ if ((trk1 = OnTrackIgnore(&pos1,FALSE,FALSE,trimLine))!=NULL) {
+ if (IsTrack(trk1)) {
+ InfoMessage(_("Can't Split a track object"));
+ wBeep();
+ return C_CONTINUE;
+ }
+ if (!QueryTrack(trk1,Q_MODIFY_CAN_SPLIT)) {
+ onTrackInSplit = FALSE;
+ InfoMessage(_("Can't Split that Draw Object"));
+ return C_CONTINUE;
+ }
+ pos1 = pos;
+ if (IsClose(GetTrkDistance(trimLine,&pos1)*4)) {
+ if ( IsClose(GetTrkDistance(trk1,&pos1)*4)) {
+ //Iterate twice
+ for (int i=0; i<2;i++) {
+ GetTrkDistance(trimLine,&pos1);
+ GetTrkDistance(trk1,&pos1);
+ }
+ } else return C_CONTINUE;
+ } else {
+ return C_CONTINUE;
+ }
+ } else return C_CONTINUE;
+
+ ANGLE_T a = GetAngleAtPoint(trk1,pos1,NULL,NULL);
+ ANGLE_T aa = DifferenceBetweenAngles(a,FindAngle(pos1,pos));
+ if (fabs(aa)<90 ) ep0 = 1;
+ else ep0 = 0;
+
+ UndoStart( _("Trim Draw"), "TrimDraw( T%d[%d] )", GetTrkIndex(trimLine), ep0 );
+ SplitTrack( trk1, pos1, ep0, &trk2, FALSE );
+ if (trk2 ) DeleteTrack(trk2, FALSE);
+ UndoEnd();
+ MainRedraw();
+ InfoMessage( _("Select another draw object to Trim, or Space to Deselect") );
+ return C_CONTINUE;
+ break;
+ case wActionMove:
+ DYNARR_RESET(trkSeg_t,anchors_da);
+ trk = NULL;
+ if (trimState == TRIM_NONE) {
+ if ((trk0 = OnTrack( &pos, FALSE, FALSE))!=NULL && CheckTrackLayerSilent( trk0 )) {
+ if (IsTrack(trk0)) break;
+ if (QueryTrack(trk0,Q_MODIFY_CAN_SPLIT)) {
+ trk = trk0;
+ }
+ }
+ }
+ if (trimState == TRIM_LINE) {
+ coOrd pos1=pos;
+ if ((trk1 = OnTrackIgnore(&pos1,FALSE,FALSE,trimLine))!=NULL) {
+ if (IsTrack(trk1)) {
+ return C_CONTINUE;
+ }
+ pos1 = pos;
+ if (IsClose(GetTrkDistance(trimLine,&pos1)*4)) {
+ if (IsClose(GetTrkDistance(trk1,&pos1)*4)) {
+ //Iterate Twice
+ for (int i=0; i<2;i++) {
+ GetTrkDistance(trimLine,&pos1);
+ GetTrkDistance(trk1,&pos1);
+ }
+ CreateTrimAnchor(pos1, trk1, trimLine, pos);
+ }
+ }
+ }
+ }
+ break;
+ case C_REDRAW:
+ if (trk) {
+ DrawTrack(trk,&tempD,wDrawColorPreviewSelected);
+ }
+ if (trimLine) {
+ DrawTrack(trimLine,&tempD,selectedColor);
+ }
+ if (anchors_da.cnt)
+ DrawSegs( &tempD, zero, 0.0, &anchors(0), anchors_da.cnt, trackGauge, wDrawColorBlack );
+ break;
+ case C_TEXT:
+ if (action>>8 != ' ' && action>>8 != 13 )
+ return C_CONTINUE;
+ trimLine = NULL;
+ trk = NULL;
+ trimState = TRIM_NONE;
+ InfoMessage("");
+ return C_TERMINATE;
+ default: ;
+ }
+
+ return C_CONTINUE;
+}
-#include "bitmaps/splittrk.xpm"
+#include "bitmaps/split.xpm"
+#include "bitmaps/split-draw.xpm"
+#include "bitmaps/trim.xpm"
void InitCmdSplit( wMenu_p menu )
{
- AddMenuButton( menu, CmdSplitTrack, "cmdSplitTrack", _("Split Track"), wIconCreatePixMap(splittrk_xpm), LEVEL0_50, IC_STICKY|IC_POPUP|IC_CMDMENU|IC_WANT_MOVE, ACCL_SPLIT, NULL );
+ ButtonGroupBegin( _("Split"), "cmdSplitSetCmd", _("Split") );
+ AddMenuButton( menu, CmdSplitTrack, "cmdSplitTrack", _("Split Track"), wIconCreatePixMap(split_xpm[iconSize]), LEVEL0_50, IC_STICKY|IC_POPUP|IC_CMDMENU|IC_WANT_MOVE, ACCL_SPLIT, NULL);
+ AddMenuButton( menu, CmdSplitDraw, "cmdSplitDraw", _("Split Draw"), wIconCreatePixMap(split_draw_xpm[iconSize]), LEVEL0_50, IC_STICKY|IC_POPUP|IC_WANT_MOVE, ACCL_SPLITDRAW, NULL);
+ AddMenuButton( menu, CmdTrimDraw, "cmdTrimDraw", _("Trim Draw"), wIconCreatePixMap(trim_xpm[iconSize]), LEVEL0_50, IC_STICKY|IC_POPUP|IC_WANT_MOVE, ACCL_TRIMDRAW, NULL);
+ ButtonGroupEnd();
}