diff options
Diffstat (limited to 'app/bin/cruler.c')
-rw-r--r-- | app/bin/cruler.c | 300 |
1 files changed, 277 insertions, 23 deletions
diff --git a/app/bin/cruler.c b/app/bin/cruler.c index d3f2926..1ab65b2 100644 --- a/app/bin/cruler.c +++ b/app/bin/cruler.c @@ -17,15 +17,231 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "cundo.h" +#include "cselect.h" #include "fileio.h" -#include "i18n.h" #include "param.h" #include "track.h" -#include "utility.h" +#include "misc.h" + +#define AN_OFF (0) +#define AN_FIRST (1) +#define AN_SECOND (2) +#define AN_ON (3) + + +static struct { + STATE_T state; + coOrd pos0; + coOrd pos1; + coOrd pos2; + BOOL_T isClose; + int modifyingEnd; +} An = { AN_OFF, { 0,0 }, { 0,0 } }; + + +void DrawAngle(drawCmd_p d, coOrd p0, coOrd p1, coOrd p2, wDrawColor color) +{ + char msg[512]; + trkSeg_t seg; + if ((An.state != AN_OFF) && !IsClose(FindDistance(p0,p1))) { + seg.type = SEG_STRLIN; + seg.lineWidth = 0; + seg.color = wDrawColorBlack; + seg.u.l.pos[0] = p0; + seg.u.l.pos[1] = p1; + DrawSegs(d,zero,0.0,&seg,1,trackGauge,color); + + if (!(IsClose(FindDistance(p0,p2)))) { + seg.type = SEG_STRLIN; + seg.lineWidth = 0; + seg.color = wDrawColorBlack; + seg.u.l.pos[0] = p0; + seg.u.l.pos[1] = p2; + DrawSegs(d,zero,0.0,&seg,1,trackGauge,color); + + DIST_T r = min(FindDistance(p0,p2),FindDistance(p0,p1))/2; + ANGLE_T a = DifferenceBetweenAngles(FindAngle(p0,p1),FindAngle(p0,p2)); + ANGLE_T a0; + + if (a>=0) { + a0 = FindAngle(p0,p1); + } else { + a0 = FindAngle(p0,p2); + } + ANGLE_T a1 = fabs(DifferenceBetweenAngles(FindAngle(p0,p1),FindAngle(p0,p2))); + seg.type = SEG_CRVLIN; + seg.u.c.center = p0; + seg.u.c.radius = r; + seg.u.c.a0 = a0; + seg.u.c.a1 = a1; + DrawSegs(d,zero,0.0,&seg,1,trackGauge,color); + + coOrd p; + Translate(&p, p0, a1/2+a0, r ); + seg.type = SEG_TEXT; + seg.u.t.angle = 0.0; + sprintf(msg,"RA: %0.3f",a1); + seg.u.t.string = msg; + seg.u.t.pos = p; + seg.u.t.fontSize = 10.0*d->scale; + seg.u.t.fontP = NULL; + seg.u.t.boxed = FALSE; + DrawSegs(d,zero,0.0,&seg,1,trackGauge,color); + } + } + +} + + +static STATUS_T CmdAngle( wAction_t action, coOrd pos ) +{ + switch (action) { + + case C_START: + switch (An.state) { + case AN_OFF: + An.state = AN_ON; + break; + case AN_ON: + An.state = AN_OFF; + case AN_FIRST: + case AN_SECOND: + An.state = AN_OFF; + break; + } + return C_CONTINUE; + + case C_DOWN: + switch (An.state) { + case AN_OFF: + case AN_ON: + An.pos0 = An.pos1 = An.pos2 = pos; + An.state = AN_FIRST; + InfoMessage( "Drag out base line" ); + break; + case AN_FIRST: + An.pos2 = pos; + An.state = AN_SECOND; + InfoMessage( "Drag Angle" ); + break; + } + return C_CONTINUE; + + case C_MOVE: + //Lock to 90 degrees with CTRL + if (MyGetKeyState()&WKEY_CTRL) { + ANGLE_T line_angle; + if (An.state == AN_FIRST) { line_angle = 0.0; } + else { line_angle = FindAngle(An.pos0,An.pos1); } + DIST_T l = FindDistance(An.pos0, pos); + if (!IsClose(l)) { + ANGLE_T angle2 = NormalizeAngle(FindAngle(An.pos0, pos)-line_angle); + int oct = (int)((angle2 + 22.5) / 45.0); + l = fabs(l*cos(D2R(angle2-oct*45))); + Translate( &pos, An.pos0, oct*45.0+line_angle, l ); + } + } + switch (An.state) { + case AN_FIRST: + An.pos1 = An.pos2 = pos; + break; + case AN_SECOND: + An.pos2 = pos; + break; + default:; + } + if (An.state == AN_FIRST) { + InfoMessage( "Base Angle %0.3f",FindAngle(An.pos0,An.pos1)); + } + if (An.state == AN_SECOND) + InfoMessage( "Base Angle %0.3f, Relative Angle %0.3f",FindAngle(An.pos0, + An.pos1), + fabs(DifferenceBetweenAngles(FindAngle(An.pos0,An.pos1),FindAngle(An.pos0, + An.pos2)))); + return C_CONTINUE; + + case C_UP: + if (An.state == AN_SECOND) { return C_TERMINATE; } + return C_CONTINUE; + + case C_REDRAW: + DrawHighlightBoxes(FALSE,FALSE,NULL); + HighlightSelectedTracks(NULL, TRUE, TRUE); + if (An.state != AN_OFF) { + if (!IsClose(FindDistance(An.pos1,An.pos2))) { + DrawAngle( &tempD, An.pos0, An.pos1, An.pos2, wDrawColorBlack ); + } + } + return C_CONTINUE; + + case C_CANCEL: + return C_TERMINATE; + + } + return C_CONTINUE; + +} + +STATUS_T ModifyProtractor( + wAction_t action, + coOrd pos ) +{ + switch (action&0xFF) { + case C_DOWN: + An.modifyingEnd = -1; + An.isClose = FALSE; + if ( An.state == AN_OFF ) { + return C_ERROR; + } + if ( IsClose(FindDistance( pos, An.pos0 ))) { + An.modifyingEnd = 0; + } else if ( IsClose(FindDistance( pos, An.pos1 ))) { + An.modifyingEnd = 1; + } else if ( IsClose(FindDistance( pos, An.pos2 ))) { + An.modifyingEnd = 2; + } else { + return C_ERROR; + } + break; + case C_MOVE: + if ( An.modifyingEnd == 0 ) { + An.pos0 = pos; + } else if (An.modifyingEnd == 1) { + An.pos1 = pos; + } else if (An.modifyingEnd == 2) { + An.pos2 = pos; + } + InfoMessage( "Base Angle %0.3f, Relative Angle %0.3f",FindAngle(An.pos0, + An.pos1), + fabs(DifferenceBetweenAngles(FindAngle(An.pos0,An.pos1),FindAngle(An.pos0, + An.pos2)))); + return C_CONTINUE; + case C_UP: + return C_CONTINUE; + case C_REDRAW: + DrawAngle( &tempD, An.pos0, An.pos1, An.pos2, + An.isClose?wDrawColorBlue:wDrawColorBlack ); + break; + case wActionMove: + if ( IsClose(FindDistance( pos, An.pos0 )) || + IsClose(FindDistance( pos, An.pos1 )) || + IsClose(FindDistance( pos, An.pos2 )) ) { + An.isClose = TRUE; + } else { + An.isClose = FALSE; + } + break; + default: + return C_ERROR; + } + return C_CONTINUE; +} + + /***************************************************************************** @@ -41,18 +257,30 @@ #define DR_ON (1) static struct { - STATE_T state; - coOrd pos0; - coOrd pos1; - int modifyingEnd; - } Dr = { DR_OFF, { 0,0 }, { 0,0 } }; + STATE_T state; + coOrd pos0; + coOrd pos1; + BOOL_T isClose; + int modifyingEnd; +} Dr = { DR_OFF, { 0,0 }, { 0,0 } }; + void RulerRedraw( BOOL_T demo ) { - if (Dr.state == DR_ON) - DrawRuler( &tempD, Dr.pos0, Dr.pos1, 0.0, TRUE, TRUE, wDrawColorBlack ); - if (demo) + if (programMode == MODE_TRAIN) { return; } + if (Dr.state == DR_ON) { + DrawRuler( &tempD, Dr.pos0, Dr.pos1, 0.0, TRUE, TRUE, + Dr.isClose?wDrawColorBlue:wDrawColorBlack ); + } + if (demo) { Dr.state = DR_OFF; + An.state = AN_OFF; + } + if (An.state != AN_OFF) { + DrawAngle( &tempD, An.pos0, An.pos1, An.pos2, + An.isClose?wDrawColorBlue:wDrawColorBlack); + } + } static STATUS_T CmdRuler( wAction_t action, coOrd pos ) @@ -60,6 +288,7 @@ static STATUS_T CmdRuler( wAction_t action, coOrd pos ) switch (action) { case C_START: + Dr.isClose = FALSE; switch (Dr.state) { case DR_OFF: Dr.state = DR_ON; @@ -87,47 +316,64 @@ static STATUS_T CmdRuler( wAction_t action, coOrd pos ) return C_TERMINATE; case C_REDRAW: + DrawHighlightBoxes(FALSE,FALSE,NULL); + HighlightSelectedTracks(NULL, TRUE, TRUE); if (Dr.state == DR_ON) { - DrawRuler( &tempD, Dr.pos0, Dr.pos1, 0.0, TRUE, TRUE, wDrawColorBlack ); + DrawRuler( &tempD, Dr.pos0, Dr.pos1, 0.0, TRUE, TRUE, + Dr.isClose?wDrawColorBlue:wDrawColorBlack ); } return C_CONTINUE; case C_CANCEL: return C_TERMINATE; - } + return C_CONTINUE; } + STATUS_T ModifyRuler( - wAction_t action, - coOrd pos ) + wAction_t action, + coOrd pos ) { switch (action&0xFF) { case C_DOWN: Dr.modifyingEnd = -1; - if ( Dr.state != DR_ON ) + if ( Dr.state != DR_ON ) { return C_ERROR; - if ( FindDistance( pos, Dr.pos0 ) < mainD.scale*0.25 ) { + } + if ( IsClose(FindDistance( pos, Dr.pos0 ))) { Dr.modifyingEnd = 0; - } else if ( FindDistance( pos, Dr.pos1 ) < mainD.scale*0.25 ) { + } else if ( IsClose(FindDistance( pos, Dr.pos1 ))) { Dr.modifyingEnd = 1; } else { return C_ERROR; } + break; case C_MOVE: if ( Dr.modifyingEnd == 0 ) { Dr.pos0 = pos; - } else { + } else if ( Dr.modifyingEnd == 1) { Dr.pos1 = pos; - } + } else { return C_ERROR; } InfoMessage( "%s", FormatDistance( FindDistance( Dr.pos0, Dr.pos1 ) ) ); return C_CONTINUE; case C_UP: return C_CONTINUE; case C_REDRAW: - DrawRuler( &tempD, Dr.pos0, Dr.pos1, 0.0, TRUE, TRUE, wDrawColorBlack ); + DrawRuler( &tempD, Dr.pos0, Dr.pos1, 0.0, TRUE, TRUE, + Dr.isClose?wDrawColorBlue:wDrawColorBlack ); + break; + case wActionMove: + if ( IsClose(FindDistance( pos, Dr.pos0 )) || + IsClose(FindDistance( pos, Dr.pos1 ))) { + Dr.isClose = TRUE; + An.isClose = FALSE; + } else { + Dr.isClose = FALSE; + ModifyProtractor(wActionMove,pos); + } break; default: return C_ERROR; @@ -136,9 +382,17 @@ STATUS_T ModifyRuler( } -#include "bitmaps/ruler.xpm" +#include "bitmaps/ruler.xpm3" +#include "bitmaps/protractor.xpm3" void InitCmdRuler( wMenu_p menu ) { - AddMenuButton( menu, CmdRuler, "cmdRuler", _("Ruler"), wIconCreatePixMap(ruler_xpm), LEVEL0, IC_STICKY|IC_NORESTART, ACCL_RULER, NULL ); + ButtonGroupBegin( _("Measurement"), "cmdMeasureSetCmd", _("Measurement") ); + AddMenuButton( menu, CmdRuler, "cmdRuler", _("Ruler"), + wIconCreatePixMap(ruler_xpm3[iconSize]), LEVEL0, + IC_STICKY|IC_POPUP|IC_NORESTART, ACCL_RULER, NULL ); + AddMenuButton( menu, CmdAngle, "cmdAngle", _("Protractor"), + wIconCreatePixMap(protractor_xpm3[iconSize]), LEVEL0, + IC_STICKY|IC_POPUP|IC_NORESTART, ACCL_ANGLE, NULL ); + ButtonGroupEnd(); } |