diff options
Diffstat (limited to 'app/bin')
45 files changed, 4224 insertions, 1012 deletions
diff --git a/app/bin/CMakeLists.txt b/app/bin/CMakeLists.txt index 4bc9fdc..ee0886d 100644 --- a/app/bin/CMakeLists.txt +++ b/app/bin/CMakeLists.txt @@ -65,6 +65,7 @@ SET(SOURCES bllnhlp.c cblock.c ccurve.c + ccontrol.c cdraw.c celev.c cgroup.c @@ -81,8 +82,10 @@ SET(SOURCES cpull.c cruler.c cselect.c + csensor.c csnap.c csplit.c + csignal.c cstraigh.c cstruct.c cswitchmotor.c @@ -98,6 +101,7 @@ SET(SOURCES dcar.c dcmpnd.c dcustmgm.c + dcontmgm.c dease.c denum.c dlayer.c @@ -106,6 +110,8 @@ SET(SOURCES dprmfile.c draw.c drawgeom.c + dxfformat.c + dxfoutput.c elev.c fileio.c i18n.c @@ -148,6 +154,7 @@ ADD_EXECUTABLE(xtrkcad WIN32 ) TARGET_LINK_LIBRARIES(xtrkcad xtrkcad-lib) TARGET_LINK_LIBRARIES(xtrkcad xtrkcad-wlib) +target_link_libraries(xtrkcad dynstring) ADD_EXECUTABLE(mkturnout ${LIN_SOURCES} @@ -169,7 +176,23 @@ ELSE(NOT WIN32) TARGET_LINK_LIBRARIES(mkturnout xtrkcad-wlib) ENDIF(NOT WIN32) +# for testing only, should be IF(APPLE) ... +IF(APPLE) + ADD_EXECUTABLE( helphelper helphelper.c ) + FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation) + FIND_LIBRARY(CARBON_LIBRARY Carbon) + TARGET_lINK_LIBRARIES(helphelper ${COREFOUNDATION_LIBRARY} ${CARBON_LIBRARY}) + INSTALL( + TARGETS helphelper + RUNTIME DESTINATION ${XTRKCAD_BIN_INSTALL_DIR} + ) +ENDIF(APPLE) + INSTALL( TARGETS xtrkcad RUNTIME DESTINATION ${XTRKCAD_BIN_INSTALL_DIR} ) + +if(XTRKCAD_TESTING AND CMOCKA_FOUND) + add_subdirectory( unittest ) +endif() diff --git a/app/bin/acclkeys.h b/app/bin/acclkeys.h index 2d60510..09bd9bb 100644 --- a/app/bin/acclkeys.h +++ b/app/bin/acclkeys.h @@ -113,6 +113,7 @@ #define ACCL_GROUP (WCTL+WSHIFT+'g') #define ACCL_UNGROUP (WCTL+WSHIFT+'u') #define ACCL_CUSTMGM (WALT+WCTL+'u') +#define ACCL_CONTMGM (WALT+WCTL+'c') #define ACCL_CARINV (WALT+WCTL+'v') #define ACCL_LAYERS (WALT+WCTL+'y') #define ACCL_SETCURLAYER (0) diff --git a/app/bin/bitmaps/block.xpm b/app/bin/bitmaps/block.xpm new file mode 100644 index 0000000..232d859 --- /dev/null +++ b/app/bin/bitmaps/block.xpm @@ -0,0 +1,24 @@ +/* XPM */
+static char * block_xpm[] = {
+"16 16 5 1",
+" c None",
+". c #2E3436",
+"+ c #00FFFF",
+"@ c #25E100",
+"# c #EF2929",
+".. . ",
+"... ... ",
+" .....++ @@@ ",
+" ...+++ @@@@@ ",
+" ...+++ @@@@@ ",
+"...++++ @@@@@ ",
+" .++++++ @@@ ",
+" ++ +++ ",
+" +++ + ",
+" ### +++ +++ ",
+" ##### +++++..",
+" ##### +++...",
+" ##### +++... ",
+" ### +++.... ",
+" +......",
+" .. ..."};
diff --git a/app/bin/bitmaps/blockdel.xpm b/app/bin/bitmaps/blockdel.xpm deleted file mode 100644 index 5a02815..0000000 --- a/app/bin/bitmaps/blockdel.xpm +++ /dev/null @@ -1,52 +0,0 @@ -/* XPM */ -static char * blockdel_xpm[] = { -"16 16 33 1", -" c None", -". c #FE0C28", -"+ c #FE102B", -"@ c #D1FCD1", -"# c #D2FCD2", -"$ c #FF0000", -"% c #FF102A", -"& c #D3FCD3", -"* c #FF0101", -"= c #000000", -"- c #C38790", -"; c #FE0D29", -"> c #B2A8AA", -", c #ACB5B7", -"' c #FE122B", -") c #ACB6B7", -"! c #DE5162", -"~ c #B5A0A2", -"{ c #F51819", -"] c #FE0A23", -"^ c #D66070", -"/ c #FF0202", -"( c #C67C7E", -"_ c #B6A0A5", -": c #FF0303", -"< c #FFF5F5", -"[ c #FEEEEE", -"} c #FFF6F6", -"| c #FDF1F1", -"1 c #FE142F", -"2 c #FFF0F0", -"3 c #FD102C", -"4 c #FE0D28", -" ", -" .+ @# $$", -" %.. @& $$ ", -" .. *$$ ", -" = .. $$ = ", -" = -.; $$> = ", -" = , .'$$ , = ", -"=== ,)!$$~,, ===", -"=== ,,{$]^,, ===", -" = ,/$ +. , = ", -" = ($ .._ = ", -" $: < .+ ", -" $* [}| 1. ", -" $$ 2} .3 ", -" *$ 4. ", -" * . "}; diff --git a/app/bin/bitmaps/blockedit.xpm b/app/bin/bitmaps/blockedit.xpm deleted file mode 100644 index cfe3e5e..0000000 --- a/app/bin/bitmaps/blockedit.xpm +++ /dev/null @@ -1,89 +0,0 @@ -/* XPM */ -static char * blockedit_xpm[] = { -"16 16 70 1", -" c None", -". c #028D05", -"+ c #008B04", -"@ c #815C14", -"# c #C88F21", -"$ c #6AC66C", -"% c #94DA95", -"& c #008C03", -"* c #008D03", -"= c #875F15", -"- c #CA8F22", -"; c #CB9022", -"> c #008C04", -", c #8CD68D", -"' c #99DD9A", -") c #008B03", -"! c #8E6516", -"~ c #B7821F", -"{ c #575B0E", -"] c #976A17", -"^ c #B07D1D", -"/ c #6C4C10", -"( c #000000", -"_ c #4E610C", -": c #9F7119", -"< c #A8781C", -"[ c #5D420D", -"} c #00C3FF", -"| c #63540F", -"1 c #A7771A", -"2 c #A0711B", -"3 c #61450F", -"4 c #090601", -"5 c #704E11", -"6 c #AE7C1C", -"7 c #956B1B", -"8 c #5E5526", -"9 c #34898C", -"0 c #BA9E58", -"a c #CE972E", -"b c #C88E21", -"c c #8D661B", -"d c #4C6B4F", -"e c #00C4FF", -"f c #01C1FB", -"g c #7F7C4C", -"h c #E3D6A3", -"i c #DDC482", -"j c #82621C", -"k c #467461", -"l c #01C2FC", -"m c #C9AB64", -"n c #CBB06D", -"o c #997C3E", -"p c #6A4E10", -"q c #03BEF7", -"r c #634813", -"s c #886628", -"t c #95360D", -"u c #EE2C2C", -"v c #F46E6E", -"w c #EC1C1C", -"x c #EA0000", -"y c #F99A9A", -"z c #F9B3B3", -"A c #F37E7E", -"B c #F48080", -"C c #F16262", -"D c #EB0000", -"E c #E90000", -" .+ @#", -" $%&* =-;", -" >,'&) !;;~", -" *&&&{];;^/", -" ( &&)_:;;<[ ", -" ( } |1;;234 ", -" ( } 56;-78 ( ", -"((( }}90abcd (((", -"((( efghijkl (((", -" ( e mnop } ( ", -" ( qrst } ( ", -" uvwx ", -" yzAx ", -" BzCx ", -" DEEx ", -" "}; diff --git a/app/bin/bitmaps/blocknew.xpm b/app/bin/bitmaps/blocknew.xpm deleted file mode 100644 index 92685f4..0000000 --- a/app/bin/bitmaps/blocknew.xpm +++ /dev/null @@ -1,90 +0,0 @@ -/* XPM */ -static char * blocknew_xpm[] = { -"16 16 71 1", -" c None", -". c #028D05", -"+ c #3DA505", -"@ c #C1DB0D", -"# c #FFF417", -"$ c #FFF41A", -"% c #6AC66C", -"& c #96DC91", -"* c #7BBE08", -"= c #C2DB12", -"- c #FCF427", -"; c #FFF750", -"> c #FFF528", -", c #FFF518", -"' c #008C04", -") c #8CD68D", -"! c #A9E084", -"~ c #9CCC0B", -"{ c #E4EA1B", -"] c #F9F560", -"^ c #FFFAA5", -"/ c #FFF864", -"( c #FFF41E", -"_ c #008D03", -": c #40A604", -"< c #A5CF0D", -"[ c #EDED1D", -"} c #FBF676", -"| c #FFFCD0", -"1 c #FFFCD1", -"2 c #FFF878", -"3 c #FFF51F", -"4 c #FFF413", -"5 c #000000", -"6 c #008C03", -"7 c #299C05", -"8 c #95C90A", -"9 c #E4E919", -"0 c #FFF756", -"a c #F4F795", -"b c #FCFA91", -"c c #FAF255", -"d c #D3CA17", -"e c #00C3FF", -"f c #FDF215", -"g c #E6F14D", -"h c #F4F443", -"i c #EFE61C", -"j c #9B940D", -"k c #A4E36A", -"l c #D0EC42", -"m c #C3BA0E", -"n c #585404", -"o c #0DC6F2", -"p c #3ACEC6", -"q c #49D1B9", -"r c #7EDB86", -"s c #4C4901", -"t c #080700", -"u c #00C4FF", -"v c #EE2C2C", -"w c #F46E6E", -"x c #EC1C1C", -"y c #EA0000", -"z c #F99A9A", -"A c #F9B3B3", -"B c #F37E7E", -"C c #F48080", -"D c #F16262", -"E c #EB0000", -"F c #E90000", -" .+@#$$# ", -" %&*=-;;>, ", -" ')!~{]^^/( ", -" _:<[}|1234", -" 5 67890abcd ", -" 5 e f(ghij ", -" 5 e 4klmn ", -"555 eeeeeopqrst5", -"555 ueeeeeee 555", -" 5 u e 5 ", -" 5 e e 5 ", -" vwxy ", -" zABy ", -" CADy ", -" EFFy ", -" "}; diff --git a/app/bin/bitmaps/control.xpm b/app/bin/bitmaps/control.xpm new file mode 100644 index 0000000..bc73a57 --- /dev/null +++ b/app/bin/bitmaps/control.xpm @@ -0,0 +1,24 @@ +/* XPM */
+static char * control_xpm[] = {
+"16 16 5 1",
+" c None",
+". c #05FB0B",
+"+ c #000000",
+"@ c #EF2929",
+"# c #25E100",
+".+ + ",
+"+++ +++",
+" +++ +++ ",
+" +++ +++ +++ ",
+" ++++++++++ ",
+" +++@@@+++ ",
+" ++@@@@@++ ",
+" ++###@@@@++ ",
+" ++####@@@++ ",
+" ++#####@@++ ",
+" ++####@++ ",
+" +++###++++ ",
+" ++++++++++++ ",
+" +++ +++ +++ ",
+"+++ +++",
+"++ ++"};
diff --git a/app/bin/bitmaps/sensor.xpm b/app/bin/bitmaps/sensor.xpm new file mode 100644 index 0000000..6ed65a3 --- /dev/null +++ b/app/bin/bitmaps/sensor.xpm @@ -0,0 +1,22 @@ +/* XPM */
+static char * sensor_xpm[] = {
+"16 16 3 1",
+" c None",
+". c #00FFFF",
+"+ c #FFFFFF",
+" ",
+" ",
+" ..... ",
+" +.......+ ",
+" +++.....+++ ",
+" .+++...+++. ",
+" ...+++.+++... ",
+" ....+++++.... ",
+" .....+++..... ",
+" ....+++++.... ",
+" ...+++.+++... ",
+" .+++...+++. ",
+" +++.....+++ ",
+" +.......+ ",
+" ..... ",
+" "};
diff --git a/app/bin/bitmaps/signal.xpm b/app/bin/bitmaps/signal.xpm new file mode 100644 index 0000000..521adad --- /dev/null +++ b/app/bin/bitmaps/signal.xpm @@ -0,0 +1,25 @@ +/* XPM */ +static char * signal_xpm[] = { +"16 16 6 1", +" c None", +". c #000000", +"+ c #3A000B", +"@ c #C90328", +"# c #D9032B", +"$ c #F30431", +" .. ", +" .... ", +" .+$@+. ", +" .#$$#. ", +" .+$@+. ", +" .... ", +" .. ", +" .. ", +" .. ", +" .. ", +" .. ", +" .. ", +" .. ", +" .. ", +" ............ ", +" ............ "}; diff --git a/app/bin/bitmaps/square10.xbm b/app/bin/bitmaps/square10.xbm deleted file mode 100644 index d419974..0000000 --- a/app/bin/bitmaps/square10.xbm +++ /dev/null @@ -1,7 +0,0 @@ -#define square10_width 14 -#define square10_height 14 -// static unsigned char square10_bits[] = { -static char square10_bits[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff}; diff --git a/app/bin/bitmaps/switchm.xpm b/app/bin/bitmaps/switchm.xpm new file mode 100644 index 0000000..0230351 --- /dev/null +++ b/app/bin/bitmaps/switchm.xpm @@ -0,0 +1,30 @@ +/* XPM */
+static char * switchm_xpm[] = {
+"16 16 11 1",
+" c None",
+". c #EE2828",
+"+ c #EF2828",
+"@ c #EF2929",
+"# c #ED2828",
+"$ c #EE2929",
+"% c #EC2828",
+"& c #E92C2C",
+"* c #D5403F",
+"= c #2E3436",
+"- c #898A83",
+" ",
+" .+@ ",
+" ..@# ",
+" $@$ ",
+" .@@. ",
+" @@. ",
+" .@%. ",
+" &*. ",
+" = ",
+" === ",
+" == == ",
+" == == ",
+" == = ",
+" == == ",
+" === - === ",
+" == == "};
diff --git a/app/bin/bitmaps/switchmdel.xpm b/app/bin/bitmaps/switchmdel.xpm deleted file mode 100644 index a6dc5ae..0000000 --- a/app/bin/bitmaps/switchmdel.xpm +++ /dev/null @@ -1,54 +0,0 @@ -/* XPM */ -static char * switchmdel_xpm[] = { -"16 16 35 1", -" c None", -". c #CC0000", -"+ c #CB0000", -"@ c #FF0000", -"# c #FE0C28", -"$ c #FE112B", -"% c #FF0101", -"& c #F00D21", -"* c #FE142E", -"= c #F80E27", -"- c #D00103", -"; c #E80306", -"> c #FF0303", -", c #FF0611", -"' c #FF060D", -") c #FF0202", -"! c #F51022", -"~ c #FD132E", -"{ c #5A5954", -"] c #E71B32", -"^ c #FE132D", -"/ c #595C58", -"( c #575954", -"_ c #FE102C", -": c #61635F", -"< c #5A5D5A", -"[ c #545652", -"} c #5E5F5C", -"| c #555753", -"1 c #FE1530", -"2 c #5B5C58", -"3 c #626460", -"4 c #565752", -"5 c #575854", -"6 c #575A56", -" ", -" .. ", -" +.+ @ ", -" #$ ... @@% ", -" ##&.. %@@ ", -" *#=-. @@ ", -" ##;@> ", -" ,@' ", -" )@!#~ ", -" %@ {]#^ ", -" @@ /( #_ ", -" @@ :< # ", -" @@ [ }| 1# ", -"@@ 2 #$ ", -" 3 # ", -" 4 56 | "}; diff --git a/app/bin/bitmaps/switchmedit.xpm b/app/bin/bitmaps/switchmedit.xpm deleted file mode 100644 index 05168b2..0000000 --- a/app/bin/bitmaps/switchmedit.xpm +++ /dev/null @@ -1,78 +0,0 @@ -/* XPM */ -static char * switchmedit_xpm[] = { -"16 16 59 1", -" c None", -". c #6F4D10", -"+ c #A0711A", -"@ c #EF2828", -"# c #EF2929", -"$ c #704E10", -"% c #A9781B", -"& c #CB9022", -"* c #EE2828", -"= c #ED2828", -"- c #B07D1D", -"; c #EE2929", -"> c #715010", -", c #B7821E", -"' c #CA8F22", -") c #9B6C1A", -"! c #71510F", -"~ c #BC851F", -"{ c #C98E22", -"] c #906717", -"^ c #684A0F", -"/ c #F02929", -"( c #755311", -"_ c #BF8820", -": c #C68D21", -"< c #886116", -"[ c #674A10", -"} c #D92D24", -"| c #775511", -"1 c #C38B21", -"2 c #C38A21", -"3 c #7E5B14", -"4 c #6D4B11", -"5 c #D03026", -"6 c #855517", -"7 c #C68D22", -"8 c #795613", -"9 c #815D19", -"0 c #C88F21", -"a c #B9831F", -"b c #725012", -"c c #896C2E", -"d c #D3AE5A", -"e c #CB9124", -"f c #B4801E", -"g c #6E4D11", -"h c #CDB678", -"i c #E2D29B", -"j c #BC9746", -"k c #8A6C2B", -"l c #D7BC78", -"m c #AD904F", -"n c #816632", -"o c #836C40", -"p c #65490C", -"q c #7A5B21", -"r c #785618", -"s c #878A85", -"t c #898B86", -" .+", -" @# $%&", -" *#= $-&&", -" ;#; >,&')", -" ## !~&{]^", -" ##/ (_&:<[ ", -" *#}|1&234 ", -" 567&_8 ", -" 90&ab ", -" cdefg ", -" hijg ", -" klmnog ", -" pqrg sg ", -" g ssg ", -" g tsg ", -" gggggggg "}; diff --git a/app/bin/bitmaps/switchmnew.xpm b/app/bin/bitmaps/switchmnew.xpm deleted file mode 100644 index 403a8b7..0000000 --- a/app/bin/bitmaps/switchmnew.xpm +++ /dev/null @@ -1,66 +0,0 @@ -/* XPM */ -static char * switchmnew_xpm[] = { -"16 16 47 1", -" c None", -". c #FFF414", -"+ c #FFF416", -"@ c #FFF314", -"# c #EF2828", -"$ c #EF2929", -"% c #FFF518", -"& c #FFF41E", -"* c #FFF639", -"= c #FFF52B", -"- c #FFF41A", -"; c #FFF512", -"> c #EE2828", -", c #ED2828", -"' c #FFF513", -") c #FFF521", -"! c #FFF969", -"~ c #FFFA92", -"{ c #FFF97C", -"] c #FFF63B", -"^ c #FFF317", -"/ c #EE2929", -"( c #FFF417", -"_ c #FFF63C", -": c #FFFA95", -"< c #FFFDE7", -"[ c #FFFBB3", -"} c #FFF75C", -"| c #FFF51B", -"1 c #FFF531", -"2 c #FFF980", -"3 c #FFFBB5", -"4 c #FFFA98", -"5 c #FFF64C", -"6 c #F35820", -"7 c #FFF63E", -"8 c #FFF74D", -"9 c #FFF51F", -"0 c #FFF515", -"a c #EC2828", -"b c #FFF312", -"c c #FFF319", -"d c #E92C2C", -"e c #D5403F", -"f c #898A83", -"g c #8B7247", -"h c #8A8577", -" .+@ ", -" #$ %&*=-; ", -" >$, ')!~{]^ ", -" /$/ (_:<[}| ", -" $$ (12345- ", -" $$6 |7}890 ", -" >$a bc|-0 ", -" de ", -" f ", -" g ", -" gg ", -" ghf ", -" g fg ", -" g f g ", -" g f g ", -" gggggggg "}; diff --git a/app/bin/bitmaps/switchmotormark.xbm b/app/bin/bitmaps/switchmotormark.xbm deleted file mode 100644 index 7a476d9..0000000 --- a/app/bin/bitmaps/switchmotormark.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define switchmotormark_width 16 -#define switchmotormark_height 16 -static char switchmotormark_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x3F, - 0xC8, 0x3F, 0xFC, 0x3F, 0xFC, 0x3F, 0xC8, 0x3F, 0xC8, 0x3F, 0x08, 0x00, - 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, }; diff --git a/app/bin/cblock.c b/app/bin/cblock.c index 5b728d0..3c627e9 100644 --- a/app/bin/cblock.c +++ b/app/bin/cblock.c @@ -1,6 +1,7 @@ /** \file cblock.c * Implement blocks: a group of trackwork with a single occ. detector - * Created by Robert Heller on Thu Mar 12 09:43:02 2009 + */ +/* Created by Robert Heller on Thu Mar 12 09:43:02 2009 * ------------------------------------------------------------------ * Modification History: $Log: not supported by cvs2svn $ * Modification History: Revision 1.4 2009/09/16 18:32:24 m_fischer @@ -47,17 +48,14 @@ #include <ctype.h> #include "track.h" +#include "trackx.h" #include "compound.h" #include "i18n.h" EXPORT TRKTYP_T T_BLOCK = -1; -#define BLOCKCMD - static int log_block = 0; -#ifdef BLOCKCMD - static void NoDrawLine(drawCmd_p d, coOrd p0, coOrd p1, wDrawWidth width, wDrawColor color ) {} static void NoDrawArc(drawCmd_p d, coOrd p, DIST_T r, ANGLE_T angle0, @@ -99,17 +97,37 @@ static paramData_t blockPLs[] = { /*1*/ { PD_STRING, blockScript, "script", PDO_NOPREF, (void*)350, N_("Script") } }; static paramGroup_t blockPG = { "block", 0, blockPLs, sizeof blockPLs/sizeof blockPLs[0] }; -static dynArr_t blockTrk_da; -#define blockTrk(N) DYNARR_N( track_p , blockTrk_da, N ) static wWin_p blockW; -#endif + +static char blockEditName[STR_SHORT_SIZE]; +static char blockEditScript[STR_LONG_SIZE]; +static char blockEditSegs[STR_LONG_SIZE]; +static track_p blockEditTrack; + +static paramData_t blockEditPLs[] = { +/*0*/ { PD_STRING, blockEditName, "name", PDO_NOPREF, (void*)200, N_("Name") }, +/*1*/ { PD_STRING, blockEditScript, "script", PDO_NOPREF, (void*)350, N_("Script") }, +/*2*/ { PD_STRING, blockEditSegs, "segments", PDO_NOPREF, (void*)350, N_("Segments"), BO_READONLY }, +}; +static paramGroup_t blockEditPG = { "block", 0, blockEditPLs, sizeof blockEditPLs/sizeof blockEditPLs[0] }; +static wWin_p blockEditW; + +typedef struct btrackinfo_t { + track_p t; + TRKINX_T i; +} btrackinfo_t, *btrackinfo_p; + +static dynArr_t blockTrk_da; +#define blockTrk(N) DYNARR_N( btrackinfo_t , blockTrk_da, N ) + typedef struct blockData_t { - char * name; - char * script; - wIndex_t numTracks; - track_p trackList; + char * name; + char * script; + BOOL_T IsHilite; + wIndex_t numTracks; + btrackinfo_t trackList; } blockData_t, *blockData_p; static blockData_p GetblockData ( track_p trk ) @@ -179,9 +197,9 @@ static DIST_T DistanceBlock (track_p t, coOrd * p ) DIST_T closest, current; int iTrk = 1; - closest = GetTrkDistance ((&(xx->trackList))[0], *p); + closest = GetTrkDistance ((&(xx->trackList))[0].t, *p); for (; iTrk < xx->numTracks; iTrk++) { - current = GetTrkDistance ((&(xx->trackList))[iTrk], *p); + current = GetTrkDistance ((&(xx->trackList))[iTrk].t, *p); if (current < closest) closest = current; } return closest; @@ -212,11 +230,12 @@ static void DescribeBlock (track_p trk, char * str, CSIZE_T len ) blockData.script[STR_LONG_SIZE-1] = '\0'; blockData.length = 0; if (xx->numTracks > 0) { - blockData.endPt[0] = GetTrkEndPos((&(xx->trackList))[0],0); + blockData.endPt[0] = GetTrkEndPos((&(xx->trackList))[0].t,0); } for (tcount = 0; tcount < xx->numTracks; tcount++) { - blockData.length += GetTrkLength((&(xx->trackList))[tcount],0,1); - lastTrk = (&(xx->trackList))[tcount]; + if ((&(xx->trackList))[tcount].t == NULL) continue; + blockData.length += GetTrkLength((&(xx->trackList))[tcount].t,0,1); + lastTrk = (&(xx->trackList))[tcount].t; } if (lastTrk != NULL) blockData.endPt[1] = GetTrkEndPos(lastTrk,1); blockDesc[E0].mode = @@ -228,7 +247,7 @@ static void DescribeBlock (track_p trk, char * str, CSIZE_T len ) } -static blockDebug (track_p trk) +static int blockDebug (track_p trk) { wIndex_t iTrack; blockData_p xx = GetblockData(trk); @@ -238,10 +257,11 @@ static blockDebug (track_p trk) LOG( log_block, 1, ("*** blockDebug(): script = \"%s\"\n",xx->script)) LOG( log_block, 1, ("*** blockDebug(): numTracks = %d\n",xx->numTracks)) for (iTrack = 0; iTrack < xx->numTracks; iTrack++) { - LOG( log_block, 1, ("*** blockDebug(): trackList[%d] = T%d, ",iTrack,GetTrkIndex((&(xx->trackList))[iTrack]))) - LOG( log_block, 1, ("%s\n",GetTrkTypeName((&(xx->trackList))[iTrack]))) + if ((&(xx->trackList))[iTrack].t == NULL) continue; + LOG( log_block, 1, ("*** blockDebug(): trackList[%d] = T%d, ",iTrack,GetTrkIndex((&(xx->trackList))[iTrack].t))) + LOG( log_block, 1, ("%s\n",GetTrkTypeName((&(xx->trackList))[iTrack].t))) } - + return(0); } static BOOL_T blockCheckContigiousPath() @@ -251,14 +271,14 @@ static BOOL_T blockCheckContigiousPath() track_p trk, trk1; DIST_T dist; ANGLE_T angle; - int pathElemStart = 0; + /*int pathElemStart = 0;*/ coOrd endPtOrig = zero; BOOL_T IsConnectedP; trkEndPt_p endPtP; DYNARR_RESET( trkEndPt_t, tempEndPts_da ); for ( inx=0; inx<blockTrk_da.cnt; inx++ ) { - trk = blockTrk(inx); + trk = blockTrk(inx).t; epCnt = GetTrkEndPtCnt(trk); IsConnectedP = FALSE; for ( ep=0; ep<epCnt; ep++ ) { @@ -297,7 +317,11 @@ static BOOL_T blockCheckContigiousPath() static void DeleteBlock ( track_p t ) { - blockData_p xx = GetblockData(t); + LOG( log_block, 1, ("*** DeleteBlock(%p)\n",t)) + blockData_p xx = GetblockData(t); + LOG( log_block, 1, ("*** DeleteBlock(): index is %d\n",GetTrkIndex(t))) + LOG( log_block, 1, ("*** DeleteBlock(): xx = %p, xx->name = %p, xx->script = %p\n", + xx,xx->name,xx->script)) MyFree(xx->name); xx->name = NULL; MyFree(xx->script); xx->script = NULL; } @@ -311,8 +335,9 @@ static BOOL_T WriteBlock ( track_p t, FILE * f ) rc &= fprintf(f, "BLOCK %d \"%s\" \"%s\"\n", GetTrkIndex(t), xx->name, xx->script)>0; for (iTrack = 0; iTrack < xx->numTracks && rc; iTrack++) { + if ((&(xx->trackList))[iTrack].t == NULL) continue; rc &= fprintf(f, "\tTRK %d\n", - GetTrkIndex((&(xx->trackList))[iTrack]))>0; + GetTrkIndex((&(xx->trackList))[iTrack].t))>0; } rc &= fprintf( f, "\tEND\n" )>0; return rc; @@ -334,7 +359,7 @@ static void ReadBlock ( char * line ) if (!GetArgs(line+6,"dqq",&index,&name,&script)) { return; } - DYNARR_RESET( track_p , blockTrk_da ); + DYNARR_RESET( btrackinfo_p , blockTrk_da ); while ( (cp = GetNextLine()) != NULL ) { while (isspace((unsigned char)*cp)) cp++; if ( strncmp( cp, "END", 3 ) == 0 ) { @@ -345,28 +370,49 @@ static void ReadBlock ( char * line ) } if ( strncmp( cp, "TRK", 3 ) == 0 ) { if (!GetArgs(cp+4,"d",&trkindex)) return; - trk = FindTrack(trkindex); - DYNARR_APPEND( track_p *, blockTrk_da, 10 ); - blockTrk(blockTrk_da.cnt-1) = trk; + /*trk = FindTrack(trkindex);*/ + DYNARR_APPEND( btrackinfo_p *, blockTrk_da, 10 ); + blockTrk(blockTrk_da.cnt-1).i = trkindex; } } - blockCheckContigiousPath(); - trk = NewTrack(index, T_BLOCK, tempEndPts_da.cnt, sizeof(blockData_t)+(sizeof(track_p)*(blockTrk_da.cnt-1))+1); + /*blockCheckContigiousPath(); save for ResolveBlockTracks */ + trk = NewTrack(index, T_BLOCK, tempEndPts_da.cnt, sizeof(blockData_t)+(sizeof(btrackinfo_t)*(blockTrk_da.cnt-1))+1); for ( ep=0; ep<tempEndPts_da.cnt; ep++) { endPtP = &tempEndPts(ep); SetTrkEndPoint( trk, ep, endPtP->pos, endPtP->angle ); } - xx = GetblockData( trk ); - xx->name = name; - xx->script = script; + xx = GetblockData( trk ); + LOG( log_block, 1, ("*** ReadBlock(): trk = %p (%d), xx = %p\n",trk,GetTrkIndex(trk),xx)) + LOG( log_block, 1, ("*** ReadBlock(): name = %p, script = %p\n",name,script)) + xx->name = name; + xx->script = script; + xx->IsHilite = FALSE; xx->numTracks = blockTrk_da.cnt; for (iTrack = 0; iTrack < blockTrk_da.cnt; iTrack++) { - LOG( log_block, 1, ("*** ReadBlock(): copying track T%d\n",GetTrkIndex(blockTrk(iTrack)))) - (&(xx->trackList))[iTrack] = blockTrk(iTrack); + LOG( log_block, 1, ("*** ReadBlock(): copying track T%d\n",GetTrkIndex(blockTrk(iTrack).t))) + memcpy((void*)&((&(xx->trackList))[iTrack]),(void*)&(blockTrk(iTrack)),sizeof(btrackinfo_t)); } blockDebug(trk); } +EXPORT void ResolveBlockTrack ( track_p trk ) +{ + LOG( log_block, 1, ("*** ResolveBlockTrack(%p)\n",trk)) + blockData_p xx; + track_p t_trk; + wIndex_t iTrack; + if (GetTrkType(trk) != T_BLOCK) return; + LOG( log_block, 1, ("*** ResolveBlockTrack(%d)\n",GetTrkIndex(trk))) + xx = GetblockData(trk); + for (iTrack = 0; iTrack < xx->numTracks; iTrack++) { + t_trk = FindTrack((&(xx->trackList))[iTrack].i); + if (t_trk == NULL) { + NoticeMessage( _("resolveBlockTrack: T%d[%d]: T%d doesn't exist"), _("Continue"), NULL, GetTrkIndex(trk), iTrack, (&(xx->trackList))[iTrack].i ); + } + (&(xx->trackList))[iTrack].t = t_trk; + LOG( log_block, 1, ("*** ResolveBlockTrack(): %d (%d): %p\n",iTrack,(&(xx->trackList))[iTrack].i,t_trk)) + } +} static void MoveBlock (track_p trk, coOrd orig ) {} static void RotateBlock (track_p trk, coOrd orig, ANGLE_T angle ) {} @@ -407,12 +453,11 @@ static trackCmd_t blockCmds = { -#ifdef BLOCKCMD static BOOL_T TrackInBlock (track_p trk, track_p blk) { wIndex_t iTrack; blockData_p xx = GetblockData(blk); for (iTrack = 0; iTrack < xx->numTracks; iTrack++) { - if (trk == (&(xx->trackList))[iTrack]) return TRUE; + if (trk == (&(xx->trackList))[iTrack].t) return TRUE; } return FALSE; } @@ -435,11 +480,11 @@ static void BlockOk ( void * junk ) trkEndPt_p endPtP; LOG( log_block, 1, ("*** BlockOk()\n")) - DYNARR_RESET( track_p *, blockTrk_da ); + DYNARR_RESET( btrackinfo_p *, blockTrk_da ); ParamUpdate( &blockPG ); if ( blockName[0]==0 ) { - NoticeMessage( 0, "Block must have a name!", _("Ok")); + NoticeMessage( _("Block must have a name!"), _("Ok"), NULL); return; } wDrawDelayUpdate( mainD.d, TRUE ); @@ -450,9 +495,10 @@ static void BlockOk ( void * junk ) while ( TrackIterate( &trk ) ) { if ( GetTrkSelected( trk ) ) { if ( IsTrack(trk) ) { - DYNARR_APPEND( track_p *, blockTrk_da, 10 ); + DYNARR_APPEND( btrackinfo_p *, blockTrk_da, 10 ); LOG( log_block, 1, ("*** BlockOk(): adding track T%d\n",GetTrkIndex(trk))) - blockTrk(blockTrk_da.cnt-1) = trk; + blockTrk(blockTrk_da.cnt-1).t = trk; + blockTrk(blockTrk_da.cnt-1).i = GetTrkIndex(trk); } } } @@ -474,18 +520,21 @@ static void BlockOk ( void * junk ) UndoStart( _("Create block"), "Create block" ); /* Create a block object */ LOG( log_block, 1, ("*** BlockOk(): %d tracks in block\n",blockTrk_da.cnt)) - trk = NewTrack(0, T_BLOCK, tempEndPts_da.cnt, sizeof(blockData_t)+(sizeof(track_p)*(blockTrk_da.cnt-1))+1); + trk = NewTrack(0, T_BLOCK, tempEndPts_da.cnt, sizeof(blockData_t)+(sizeof(btrackinfo_t)*(blockTrk_da.cnt-1))+1); for ( ep=0; ep<tempEndPts_da.cnt; ep++) { endPtP = &tempEndPts(ep); SetTrkEndPoint( trk, ep, endPtP->pos, endPtP->angle ); } - xx = GetblockData( trk ); + + xx = GetblockData( trk ); + LOG(log_block, 1, ("*** BlockOk(): trk = %p (%d), xx = %p\n", trk, GetTrkIndex(trk), xx)) xx->name = MyStrdup(blockName); xx->script = MyStrdup(blockScript); + xx->IsHilite = FALSE; xx->numTracks = blockTrk_da.cnt; for (iTrack = 0; iTrack < blockTrk_da.cnt; iTrack++) { - LOG( log_block, 1, ("*** BlockOk(): copying track T%d\n",GetTrkIndex(blockTrk(iTrack)))) - (&(xx->trackList))[iTrack] = blockTrk(iTrack); + LOG( log_block, 1, ("*** BlockOk(): copying track T%d\n",GetTrkIndex(blockTrk(iTrack).t))) + memcpy((void*)&(&(xx->trackList))[iTrack],(void*)&blockTrk(iTrack),sizeof(btrackinfo_t)); } blockDebug(trk); UndoEnd(); @@ -534,7 +583,7 @@ static STATUS_T CmdBlockCreate( wAction_t action, coOrd pos ) LOG( log_block, 1, ("*** CmdBlockAction(%08x,{%f,%f})\n",action,pos.x,pos.y)) switch (action & 0xFF) { case C_START: - fprintf(stderr,"*** CmdBlockCreate(): C_START\n"); + LOG( log_block, 1,("*** CmdBlockCreate(): C_START\n")) NewBlockDialog(); return C_TERMINATE; default: @@ -542,6 +591,7 @@ static STATUS_T CmdBlockCreate( wAction_t action, coOrd pos ) } } +#if 0 extern BOOL_T inDescribeCmd; static STATUS_T CmdBlockEdit( wAction_t action, coOrd pos ) @@ -613,14 +663,13 @@ static STATUS_T CmdBlockDelete( wAction_t action, coOrd pos ) } - #define BLOCK_CREATE 0 #define BLOCK_EDIT 1 #define BLOCK_DELETE 2 static STATUS_T CmdBlock (wAction_t action, coOrd pos ) { - fprintf(stderr,"*** CmdBlock(%08x,{%f,%f})\n",action,pos.x,pos.y); + LOG( log_block, 1, ("*** CmdBlock(%08x,{%f,%f})\n",action,pos.x,pos.y)) switch ((long)commandContext) { case BLOCK_CREATE: return CmdBlockCreate(action,pos); @@ -629,23 +678,225 @@ static STATUS_T CmdBlock (wAction_t action, coOrd pos ) default: return C_TERMINATE; } } +#endif -#include "bitmaps/blocknew.xpm" -#include "bitmaps/blockedit.xpm" -#include "bitmaps/blockdel.xpm" +EXPORT void CheckDeleteBlock (track_p t) +{ + track_p blk; + blockData_p xx; + + blk = FindBlock(t); + if (blk == NULL) return; + xx = GetblockData(blk); + NoticeMessage(_("Deleting block %s"),_("Ok"),NULL,xx->name); + DeleteTrack(blk,FALSE); +} + +static void BlockEditOk ( void * junk ) +{ + blockData_p xx; + track_p trk; + + LOG( log_block, 1, ("*** BlockEditOk()\n")) + ParamUpdate (&blockEditPG ); + if ( blockEditName[0]==0 ) { + NoticeMessage( _("Block must have a name!"), _("Ok"), NULL); + return; + } + wDrawDelayUpdate( mainD.d, TRUE ); + UndoStart( _("Modify Block"), "Modify Block" ); + trk = blockEditTrack; + xx = GetblockData( trk ); + xx->name = MyStrdup(blockEditName); + xx->script = MyStrdup(blockEditScript); + blockDebug(trk); + UndoEnd(); + wHide( blockEditW ); +} + + +static void EditBlock (track_p trk) +{ + blockData_p xx = GetblockData(trk); + wIndex_t iTrack; + BOOL_T needComma = FALSE; + char temp[32]; + + strncpy(blockEditName,xx->name,STR_SHORT_SIZE); + strncpy(blockEditScript,xx->script,STR_LONG_SIZE); + blockEditSegs[0] = '\0'; + for (iTrack = 0; iTrack < xx->numTracks ; iTrack++) { + if ((&(xx->trackList))[iTrack].t == NULL) continue; + sprintf(temp,"%d",GetTrkIndex((&(xx->trackList))[iTrack].t)); + if (needComma) strcat(blockEditSegs,", "); + strcat(blockEditSegs,temp); + needComma = TRUE; + } + blockEditTrack = trk; + if ( !blockEditW ) { + ParamRegister( &blockEditPG ); + blockEditW = ParamCreateDialog (&blockEditPG, + MakeWindowTitle(_("Edit block")), + _("Ok"), BlockEditOk, + wHide, TRUE, NULL, F_BLOCK, + NULL ); + } + ParamLoadControls( &blockEditPG ); + sprintf( message, _("Edit block %d"), GetTrkIndex(trk) ); + wWinSetTitle( blockEditW, message ); + wShow (blockEditW); +} + +static coOrd blkhiliteOrig, blkhiliteSize; +static POS_T blkhiliteBorder; +static wDrawColor blkhiliteColor = 0; +static void DrawBlockTrackHilite( void ) +{ + wPos_t x, y, w, h; + if (blkhiliteColor==0) + blkhiliteColor = wDrawColorGray(87); + w = (wPos_t)((blkhiliteSize.x/mainD.scale)*mainD.dpi+0.5); + h = (wPos_t)((blkhiliteSize.y/mainD.scale)*mainD.dpi+0.5); + mainD.CoOrd2Pix(&mainD,blkhiliteOrig,&x,&y); + wDrawFilledRectangle( mainD.d, x, y, w, h, blkhiliteColor, wDrawOptTemp ); +} + + +static int BlockMgmProc ( int cmd, void * data ) +{ + track_p trk = (track_p) data; + blockData_p xx = GetblockData(trk); + wIndex_t iTrack; + BOOL_T needComma = FALSE; + char temp[32]; + /*char msg[STR_SIZE];*/ + coOrd tempOrig, tempSize; + BOOL_T first = TRUE; + + switch ( cmd ) { + case CONTMGM_CAN_EDIT: + return TRUE; + break; + case CONTMGM_DO_EDIT: + EditBlock (trk); + /*inDescribeCmd = TRUE;*/ + /*DescribeTrack (trk, msg, sizeof msg );*/ + /*InfoMessage( msg );*/ + return TRUE; + break; + case CONTMGM_CAN_DELETE: + return TRUE; + break; + case CONTMGM_DO_DELETE: + DeleteTrack (trk, FALSE); + return TRUE; + break; + case CONTMGM_DO_HILIGHT: + if (!xx->IsHilite) { + blkhiliteBorder = mainD.scale*0.1; + if ( blkhiliteBorder < trackGauge ) blkhiliteBorder = trackGauge; + first = TRUE; + for (iTrack = 0; iTrack < xx->numTracks ; iTrack++) { + if ((&(xx->trackList))[iTrack].t == NULL) continue; + GetBoundingBox( (&(xx->trackList))[iTrack].t, &tempSize, &tempOrig ); + if (first) { + blkhiliteOrig = tempOrig; + blkhiliteSize = tempSize; + first = FALSE; + } else { + if (tempSize.x > blkhiliteSize.x) + blkhiliteSize.x = tempSize.x; + if (tempSize.y > blkhiliteSize.y) + blkhiliteSize.y = tempSize.y; + if (tempOrig.x < blkhiliteOrig.x) + blkhiliteOrig.x = tempOrig.x; + if (tempOrig.y < blkhiliteOrig.y) + blkhiliteOrig.y = tempOrig.y; + } + } + blkhiliteOrig.x -= blkhiliteBorder; + blkhiliteOrig.y -= blkhiliteBorder; + blkhiliteSize.x -= blkhiliteOrig.x-blkhiliteBorder; + blkhiliteSize.y -= blkhiliteOrig.y-blkhiliteBorder; + DrawBlockTrackHilite(); + xx->IsHilite = TRUE; + } + break; + case CONTMGM_UN_HILIGHT: + if (xx->IsHilite) { + blkhiliteBorder = mainD.scale*0.1; + if ( blkhiliteBorder < trackGauge ) blkhiliteBorder = trackGauge; + first = TRUE; + for (iTrack = 0; iTrack < xx->numTracks ; iTrack++) { + if ((&(xx->trackList))[iTrack].t == NULL) continue; + GetBoundingBox( (&(xx->trackList))[iTrack].t, &tempSize, &tempOrig ); + if (first) { + blkhiliteOrig = tempOrig; + blkhiliteSize = tempSize; + first = FALSE; + } else { + if (tempSize.x > blkhiliteSize.x) + blkhiliteSize.x = tempSize.x; + if (tempSize.y > blkhiliteSize.y) + blkhiliteSize.y = tempSize.y; + if (tempOrig.x < blkhiliteOrig.x) + blkhiliteOrig.x = tempOrig.x; + if (tempOrig.y < blkhiliteOrig.y) + blkhiliteOrig.y = tempOrig.y; + } + } + blkhiliteOrig.x -= blkhiliteBorder; + blkhiliteOrig.y -= blkhiliteBorder; + blkhiliteSize.x -= blkhiliteOrig.x-blkhiliteBorder; + blkhiliteSize.y -= blkhiliteOrig.y-blkhiliteBorder; + DrawBlockTrackHilite(); + xx->IsHilite = FALSE; + } + break; + case CONTMGM_GET_TITLE: + sprintf( message, "\t%s\t", xx->name); + for (iTrack = 0; iTrack < xx->numTracks ; iTrack++) { + if ((&(xx->trackList))[iTrack].t == NULL) continue; + sprintf(temp,"%d",GetTrkIndex((&(xx->trackList))[iTrack].t)); + if (needComma) strcat(message,", "); + strcat(message,temp); + needComma = TRUE; + } + break; + } + return FALSE; +} + + +//#include "bitmaps/blocknew.xpm" +//#include "bitmaps/blockedit.xpm" +//#include "bitmaps/blockdel.xpm" +#include "bitmaps/block.xpm" + +EXPORT void BlockMgmLoad( void ) +{ + track_p trk; + static wIcon_p blockI = NULL; + + if ( blockI == NULL) + blockI = wIconCreatePixMap( block_xpm ); + + TRK_ITERATE(trk) { + if (GetTrkType(trk) != T_BLOCK) continue; + ContMgmLoad( blockI, BlockMgmProc, (void *)trk ); + } + +} EXPORT void InitCmdBlock( wMenu_p menu ) { blockName[0] = '\0'; blockScript[0] = '\0'; - ButtonGroupBegin( _("Block"), "cmdBlockSetCmd", _("Blocks") ); - AddMenuButton( menu, CmdBlock, "cmdBlockCreate", _("Create Block"), wIconCreatePixMap(blocknew_xpm), LEVEL0_50, IC_CANCEL|IC_POPUP, ACCL_BLOCK1, (void*)BLOCK_CREATE ); - AddMenuButton( menu, CmdBlock, "cmdBlockEdit", _("Edit Block"), wIconCreatePixMap(blockedit_xpm), LEVEL0_50, IC_CANCEL|IC_POPUP, ACCL_BLOCK2, (void*)BLOCK_EDIT ); - AddMenuButton( menu, CmdBlock, "cmdBlockDelete", _("Delete Block"), wIconCreatePixMap(blockdel_xpm), LEVEL0_50, IC_CANCEL|IC_POPUP, ACCL_BLOCK3, (void*)BLOCK_DELETE ); - ButtonGroupEnd(); + AddMenuButton( menu, CmdBlockCreate, "cmdBlockCreate", _("Block"), + wIconCreatePixMap( block_xpm ), LEVEL0_50, + IC_STICKY|IC_POPUP2, ACCL_BLOCK1, NULL ); ParamRegister( &blockPG ); } -#endif EXPORT void InitTrkBlock( void ) diff --git a/app/bin/ccontrol.c b/app/bin/ccontrol.c new file mode 100644 index 0000000..9428e1a --- /dev/null +++ b/app/bin/ccontrol.c @@ -0,0 +1,597 @@ +/** \file ccontrol.c + * Controls + */ + +/* -*- C -*- **************************************************************** + * + * System : + * Module : + * Object Name : $RCSfile$ + * Revision : $Revision$ + * Date : $Date$ + * Author : $Author$ + * Created By : Robert Heller + * Created : Sun Mar 5 16:01:37 2017 + * Last Modified : <170314.1418> + * + * Description + * + * Notes + * + * History + * + **************************************************************************** + * + * Copyright (C) 2017 Robert Heller D/B/A Deepwoods Software + * 51 Locke Hill Road + * Wendell, MA 01379-9728 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * + ****************************************************************************/ + +static const char rcsid[] = "@(#) : $Id$"; + +#include <ctype.h> +#include "track.h" +#include "trackx.h" +#include "compound.h" +#include "i18n.h" + +EXPORT TRKTYP_T T_CONTROL = -1; + +static int log_control = 0; + + +#if 0 +static drawCmd_t controlD = { + NULL, + &screenDrawFuncs, + 0, + 1.0, + 0.0, + {0.0,0.0}, {0.0,0.0}, + Pix2CoOrd, CoOrd2Pix }; + +static char controlName[STR_SHORT_SIZE]; +static char controlOnScript[STR_LONG_SIZE]; +static char controlOffScript[STR_LONG_SIZE]; +#endif + +typedef struct controlData_t { + coOrd orig; + BOOL_T IsHilite; + char * name; + char * onscript; + char * offscript; +} controlData_t, *controlData_p; + +static controlData_p GetcontrolData ( track_p trk ) +{ + return (controlData_p) GetTrkExtraData(trk); +} + +#define RADIUS 6 +#define LINE 8 + +#define control_SF (3.0) + +static void DDrawControl(drawCmd_p d, coOrd orig, DIST_T scaleRatio, + wDrawColor color ) +{ + coOrd p1, p2; + + p1 = orig; + DrawFillCircle(d,p1, RADIUS * control_SF / scaleRatio,color); + Translate (&p1, orig, 45, RADIUS * control_SF / scaleRatio); + Translate (&p2, p1, 45, LINE * control_SF / scaleRatio); + DrawLine(d, p1, p2, 2, color); + Translate (&p1, orig, 45+90, RADIUS * control_SF / scaleRatio); + Translate (&p2, p1, 45+90, LINE * control_SF / scaleRatio); + DrawLine(d, p1, p2, 2, color); + Translate (&p1, orig, 45+180, RADIUS * control_SF / scaleRatio); + Translate (&p2, p1, 45+180, LINE * control_SF / scaleRatio); + DrawLine(d, p1, p2, 2, color); + Translate (&p1, orig, 45+270, RADIUS * control_SF / scaleRatio); + Translate (&p2, p1, 45+270, LINE * control_SF / scaleRatio); + DrawLine(d, p1, p2, 2, color); +} + +static void DrawControl (track_p t, drawCmd_p d, wDrawColor color ) +{ + controlData_p xx = GetcontrolData(t); + DDrawControl(d,xx->orig,GetScaleRatio(GetTrkScale(t)),color); +} + +static void ControlBoundingBox (coOrd orig, DIST_T scaleRatio, coOrd *hi, + coOrd *lo) +{ + coOrd p1, p2; + + p1 = orig; + Translate (&p1, orig, 0, -(RADIUS+LINE) * control_SF / scaleRatio); + Translate (&p2, orig, 0, (RADIUS+LINE) * control_SF / scaleRatio); + *hi = p1; *lo = p1; + if (p2.x > hi->x) hi->x = p2.x; + if (p2.x < lo->x) lo->x = p2.x; + if (p2.y > hi->y) hi->y = p2.y; + if (p2.y < lo->y) lo->y = p2.y; +} + + +static void ComputeControlBoundingBox (track_p t ) +{ + coOrd lo, hi; + controlData_p xx = GetcontrolData(t); + ControlBoundingBox(xx->orig, GetScaleRatio(GetTrkScale(t)), &hi, &lo); + SetBoundingBox(t, hi, lo); +} + +static DIST_T DistanceControl (track_p t, coOrd * p ) +{ + controlData_p xx = GetcontrolData(t); + return FindDistance(xx->orig, *p); +} + +static struct { + char name[STR_SHORT_SIZE]; + coOrd pos; + char onscript[STR_LONG_SIZE]; + char offscript[STR_LONG_SIZE]; +} controlProperties; + +typedef enum { NM, PS, ON, OF } controlDesc_e; +static descData_t controlDesc[] = { + /* NM */ { DESC_STRING, N_("Name"), &controlProperties.name }, + /* PS */ { DESC_POS, N_("Position"), &controlProperties.pos }, + /* ON */ { DESC_STRING, N_("On Script"), &controlProperties.onscript }, + /* OF */ { DESC_STRING, N_("Off Script"),&controlProperties.offscript }, + { DESC_NULL } }; + +static void UpdateControlProperties ( track_p trk, int inx, descData_p + descUpd, BOOL_T needUndoStart ) +{ + controlData_p xx = GetcontrolData(trk); + const char *thename, *theonscript, *theoffscript; + char *newName, *newOnScript, *newOffScript; + BOOL_T changed, nChanged, pChanged, onChanged, offChanged; + + switch (inx) { + case NM: + break; + case PS: + break; + case ON: + break; + case OF: + break; + case -1: + changed = nChanged = pChanged = onChanged = offChanged = FALSE; + thename = wStringGetValue( (wString_p) controlDesc[NM].control0 ); + if (strcmp(thename,xx->name) != 0) { + nChanged = changed = TRUE; + newName = MyStrdup(thename); + } + theonscript = wStringGetValue( (wString_p) controlDesc[ON].control0 ); + if (strcmp(theonscript,xx->onscript) != 0) { + onChanged = changed = TRUE; + newOnScript = MyStrdup(theonscript); + } + theoffscript = wStringGetValue( (wString_p) controlDesc[OF].control0 ); + if (strcmp(theoffscript,xx->offscript) != 0) { + offChanged = changed = TRUE; + newOffScript = MyStrdup(theoffscript); + } + if (controlProperties.pos.x != xx->orig.x || + controlProperties.pos.y != xx->orig.y) { + pChanged = changed = TRUE; + } + if (!changed) break; + if (needUndoStart) + UndoStart( _("Change Control"), "Change Control" ); + UndoModify( trk ); + if (nChanged) { + MyFree(xx->name); + xx->name = newName; + } + if (pChanged) { + UndrawNewTrack( trk ); + } + if (pChanged) { + xx->orig = controlProperties.pos; + } + if (onChanged) { + MyFree(xx->onscript); + xx->onscript = newOnScript; + } + if (offChanged) { + MyFree(xx->offscript); + xx->offscript = newOffScript; + } + if (pChanged) { + ComputeControlBoundingBox( trk ); + DrawNewTrack( trk ); + } + break; + } +} + + + + + +static void DescribeControl (track_p trk, char * str, CSIZE_T len ) +{ + controlData_p xx = GetcontrolData(trk); + + strcpy( str, _(GetTrkTypeName( trk )) ); + str++; + while (*str) { + *str = tolower((unsigned char)*str); + str++; + } + sprintf( str, _("(%d [%s]): Layer=%d, at %0.3f,%0.3f"), + GetTrkIndex(trk), + xx->name,GetTrkLayer(trk)+1, xx->orig.x, xx->orig.y); + strncpy(controlProperties.name,xx->name,STR_SHORT_SIZE-1); + controlProperties.name[STR_SHORT_SIZE-1] = '\0'; + strncpy(controlProperties.onscript,xx->onscript,STR_LONG_SIZE-1); + controlProperties.onscript[STR_LONG_SIZE-1] = '\0'; + strncpy(controlProperties.offscript,xx->offscript,STR_LONG_SIZE-1); + controlProperties.offscript[STR_LONG_SIZE-1] = '\0'; + controlProperties.pos = xx->orig; + controlDesc[NM].mode = + controlDesc[ON].mode = + controlDesc[OF].mode = DESC_NOREDRAW; + DoDescribe( _("Control"), trk, controlDesc, UpdateControlProperties ); + +} + +static void DeleteControl ( track_p trk ) +{ + controlData_p xx = GetcontrolData(trk); + MyFree(xx->name); xx->name = NULL; + MyFree(xx->onscript); xx->onscript = NULL; + MyFree(xx->offscript); xx->offscript = NULL; +} + +static BOOL_T WriteControl ( track_p t, FILE * f ) +{ + BOOL_T rc = TRUE; + controlData_p xx = GetcontrolData(t); + rc &= fprintf(f, "CONTROL %d %d %s %d %0.6f %0.6f \"%s\" \"%s\" \"%s\"\n", + GetTrkIndex(t), GetTrkLayer(t), GetTrkScaleName(t), + GetTrkVisible(t), xx->orig.x, xx->orig.y, xx->name, + xx->onscript, xx->offscript)>0; + return rc; +} + +static void ReadControl ( char * line ) +{ + wIndex_t index; + /*TRKINX_T trkindex;*/ + track_p trk; + /*char * cp = NULL;*/ + char *name; + char *onscript, *offscript; + coOrd orig; + BOOL_T visible; + char scale[10]; + wIndex_t layer; + controlData_p xx; + if (!GetArgs(line+7,"dLsdpqqq",&index,&layer,scale, &visible, &orig,&name,&onscript,&offscript)) { + return; + } + trk = NewTrack(index, T_CONTROL, 0, sizeof(controlData_t)); + SetTrkVisible(trk, visible); + SetTrkScale(trk, LookupScale( scale )); + SetTrkLayer(trk, layer); + xx = GetcontrolData ( trk ); + xx->name = name; + xx->orig = orig; + xx->onscript = onscript; + xx->offscript = offscript; + ComputeControlBoundingBox(trk); +} + +static void MoveControl (track_p trk, coOrd orig ) +{ + controlData_p xx = GetcontrolData ( trk ); + xx->orig.x += orig.x; + xx->orig.y += orig.y; + ComputeControlBoundingBox(trk); +} + +static void RotateControl (track_p trk, coOrd orig, ANGLE_T angle ) +{ +} + +static void RescaleControl (track_p trk, FLOAT_T ratio ) +{ +} + +static void FlipControl (track_p trk, coOrd orig, ANGLE_T angle ) +{ + controlData_p xx = GetcontrolData ( trk ); + FlipPoint(&(xx->orig), orig, angle); + ComputeControlBoundingBox(trk); +} + +static trackCmd_t controlCmds = { + "CONTROL", + DrawControl, + DistanceControl, + DescribeControl, + DeleteControl, + WriteControl, + ReadControl, + MoveControl, + RotateControl, + RescaleControl, + NULL, /* audit */ + NULL, /* getAngle */ + NULL, /* split */ + NULL, /* traverse */ + NULL, /* enumerate */ + NULL, /* redraw */ + NULL, /* trim */ + NULL, /* merge */ + NULL, /* modify */ + NULL, /* getLength */ + NULL, /* getTrkParams */ + NULL, /* moveEndPt */ + NULL, /* query */ + NULL, /* ungroup */ + FlipControl, /* flip */ + NULL, /* drawPositionIndicator */ + NULL, /* advancePositionIndicator */ + NULL, /* checkTraverse */ + NULL, /* makeParallel */ + NULL /* drawDesc */ +}; + +static coOrd controlEditOrig; +static track_p controlEditTrack; +static char controlEditName[STR_SHORT_SIZE]; +static char controlEditOnScript[STR_LONG_SIZE]; +static char controlEditOffScript[STR_LONG_SIZE]; + +static paramFloatRange_t r_1000_1000 = { -1000.0, 1000.0, 80 }; +static paramData_t controlEditPLs[] = { +#define I_CONTROLNAME (0) + /*0*/ { PD_STRING, controlEditName, "name", PDO_NOPREF, (void*)200, N_("Name") }, +#define I_ORIGX (1) + /*1*/ { PD_FLOAT, &controlEditOrig.x, "origx", PDO_DIM, &r_1000_1000, N_("Orgin X") }, +#define I_ORIGY (2) + /*2*/ { PD_FLOAT, &controlEditOrig.y, "origy", PDO_DIM, &r_1000_1000, N_("Origin Y") }, +#define I_CONTROLONSCRIPT (3) + /*3*/ { PD_STRING, controlEditOnScript, "script", PDO_NOPREF, (void*)350, N_("On Script") }, +#define I_CONTROLOFFSCRIPT (4) + /*4*/ { PD_STRING, controlEditOffScript, "script", PDO_NOPREF, (void*)350, N_("Off Script") }, +}; + +static paramGroup_t controlEditPG = { "controlEdit", 0, controlEditPLs, sizeof controlEditPLs/sizeof controlEditPLs[0] }; +static wWin_p controlEditW; + +static void ControlEditOk ( void * junk ) +{ + track_p trk; + controlData_p xx; + + if (controlEditTrack == NULL) { + UndoStart( _("Create Control"), "Create Control"); + trk = NewTrack(0, T_CONTROL, 0, sizeof(controlData_t)); + } else { + UndoStart( _("Modify Control"), "Modify Control"); + trk = controlEditTrack; + } + xx = GetcontrolData(trk); + xx->orig = controlEditOrig; + if ( xx->name == NULL || strncmp (xx->name, controlEditName, STR_SHORT_SIZE) != 0) { + MyFree(xx->name); + xx->name = MyStrdup(controlEditName); + } + if ( xx->onscript == NULL || strncmp (xx->onscript, controlEditOnScript, STR_LONG_SIZE) != 0) { + MyFree(xx->onscript); + xx->onscript = MyStrdup(controlEditOnScript); + } + if ( xx->offscript == NULL || strncmp (xx->offscript, controlEditOffScript, STR_LONG_SIZE) != 0) { + MyFree(xx->offscript); + xx->offscript = MyStrdup(controlEditOffScript); + } + UndoEnd(); + ComputeControlBoundingBox(trk); + DoRedraw(); + wHide( controlEditW ); +} + +#if 0 +static void ControlEditCancel ( wWin_p junk ) +{ + wHide( controlEditW ); +} +#endif + +static void EditControlDialog() +{ + controlData_p xx; + + if ( !controlEditW ) { + ParamRegister( &controlEditPG ); + controlEditW = ParamCreateDialog (&controlEditPG, + MakeWindowTitle(_("Edit control")), + _("Ok"), ControlEditOk, + wHide, TRUE, NULL, + F_BLOCK, + NULL ); + } + if (controlEditTrack == NULL) { + controlEditName[0] = '\0'; + controlEditOnScript[0] = '\0'; + controlEditOffScript[0] = '\0'; + } else { + xx = GetcontrolData ( controlEditTrack ); + strncpy(controlEditName,xx->name,STR_SHORT_SIZE); + strncpy(controlEditOnScript,xx->onscript,STR_LONG_SIZE); + strncpy(controlEditOffScript,xx->offscript,STR_LONG_SIZE); + controlEditOrig = xx->orig; + } + ParamLoadControls( &controlEditPG ); + wShow( controlEditW ); +} + +static void EditControl (track_p trk) +{ + controlEditTrack = trk; + EditControlDialog(); +} + +static void CreateNewControl (coOrd orig) +{ + controlEditOrig = orig; + controlEditTrack = NULL; + EditControlDialog(); +} + +static STATUS_T CmdControl ( wAction_t action, coOrd pos ) +{ + + + switch (action) { + case C_START: + InfoMessage(_("Place control")); + return C_CONTINUE; + case C_DOWN: + SnapPos(&pos); + DDrawControl( &tempD, pos, GetScaleRatio(curScaleInx), wDrawColorBlack ); + return C_CONTINUE; + case C_MOVE: + SnapPos(&pos); + DDrawControl( &tempD, pos, GetScaleRatio(curScaleInx), wDrawColorBlack ); + return C_CONTINUE; + case C_UP: + SnapPos(&pos); + DDrawControl( &tempD, pos, GetScaleRatio(curScaleInx), wDrawColorBlack ); + CreateNewControl(pos); + return C_TERMINATE; + case C_REDRAW: + case C_CANCEL: + DDrawControl( &tempD, pos, GetScaleRatio(curScaleInx), wDrawColorBlack ); + return C_CONTINUE; + default: + return C_CONTINUE; + } +} + +static coOrd ctlhiliteOrig, ctlhiliteSize; +static POS_T ctlhiliteBorder; +static wDrawColor ctlhiliteColor = 0; +static void DrawControlTrackHilite( void ) +{ + wPos_t x, y, w, h; + if (ctlhiliteColor==0) + ctlhiliteColor = wDrawColorGray(87); + w = (wPos_t)((ctlhiliteSize.x/mainD.scale)*mainD.dpi+0.5); + h = (wPos_t)((ctlhiliteSize.y/mainD.scale)*mainD.dpi+0.5); + mainD.CoOrd2Pix(&mainD,ctlhiliteOrig,&x,&y); + wDrawFilledRectangle( mainD.d, x, y, w, h, ctlhiliteColor, wDrawOptTemp ); +} + +static int ControlMgmProc ( int cmd, void * data ) +{ + track_p trk = (track_p) data; + controlData_p xx = GetcontrolData(trk); + /*char msg[STR_SIZE];*/ + + switch ( cmd ) { + case CONTMGM_CAN_EDIT: + return TRUE; + break; + case CONTMGM_DO_EDIT: + EditControl(trk); + return TRUE; + break; + case CONTMGM_CAN_DELETE: + return TRUE; + break; + case CONTMGM_DO_DELETE: + DeleteTrack(trk, FALSE); + return TRUE; + break; + case CONTMGM_DO_HILIGHT: + if (!xx->IsHilite) { + ctlhiliteBorder = mainD.scale*0.1; + if ( ctlhiliteBorder < trackGauge ) ctlhiliteBorder = trackGauge; + GetBoundingBox( trk, &ctlhiliteSize, &ctlhiliteOrig ); + ctlhiliteOrig.x -= ctlhiliteBorder; + ctlhiliteOrig.y -= ctlhiliteBorder; + ctlhiliteSize.x -= ctlhiliteOrig.x-ctlhiliteBorder; + ctlhiliteSize.y -= ctlhiliteOrig.y-ctlhiliteBorder; + DrawControlTrackHilite(); + xx->IsHilite = TRUE; + } + break; + case CONTMGM_UN_HILIGHT: + if (xx->IsHilite) { + ctlhiliteBorder = mainD.scale*0.1; + if ( ctlhiliteBorder < trackGauge ) ctlhiliteBorder = trackGauge; + GetBoundingBox( trk, &ctlhiliteSize, &ctlhiliteOrig ); + ctlhiliteOrig.x -= ctlhiliteBorder; + ctlhiliteOrig.y -= ctlhiliteBorder; + ctlhiliteSize.x -= ctlhiliteOrig.x-ctlhiliteBorder; + ctlhiliteSize.y -= ctlhiliteOrig.y-ctlhiliteBorder; + DrawControlTrackHilite(); + xx->IsHilite = FALSE; + } + break; + case CONTMGM_GET_TITLE: + sprintf(message,"\t%s\t",xx->name); + break; + } + return FALSE; +} + +#include "bitmaps/control.xpm" + +EXPORT void ControlMgmLoad ( void ) +{ + track_p trk; + static wIcon_p controlI = NULL; + + if (controlI == NULL) { + controlI = wIconCreatePixMap( control_xpm ); + } + + TRK_ITERATE(trk) { + if (GetTrkType(trk) != T_CONTROL) continue; + ContMgmLoad (controlI, ControlMgmProc, (void *) trk ); + } +} + +#define ACCL_CONTROL 0 + +EXPORT void InitCmdControl ( wMenu_p menu ) +{ + AddMenuButton( menu, CmdControl, "cmdControl", _("Control"), + wIconCreatePixMap( control_xpm ), LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_CONTROL, NULL ); +} + +EXPORT void InitTrkControl ( void ) +{ + T_CONTROL = InitObject ( &controlCmds ); + log_control = LogFindIndex ( "control" ); +} diff --git a/app/bin/cdraw.c b/app/bin/cdraw.c index 59e45b8..efdb51a 100644 --- a/app/bin/cdraw.c +++ b/app/bin/cdraw.c @@ -2,23 +2,23 @@ * Drawing of geometric elements */ -/* XTrkCad - Model Railroad CAD - * Copyright (C) 2005 Dave Bullis - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * 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. - */ + /* XTrkCad - Model Railroad CAD + * Copyright (C) 2005 Dave Bullis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + */ #include "track.h" #include "ccurve.h" @@ -35,31 +35,49 @@ static long fontSizeList[] = { 200, 250, 300, 350, 400, 450, 500 }; EXPORT void LoadFontSizeList( - wList_p list, - long curFontSize ) + wList_p list, + long curFontSize) { - wIndex_t curInx=0, inx1; + wIndex_t curInx = 0, inx1; int inx; - wListClear( list ); - for ( inx=0; inx<sizeof fontSizeList/sizeof fontSizeList[0]; inx++ ) { - if ( ( inx==0 || curFontSize > fontSizeList[inx-1] ) && - ( curFontSize < fontSizeList[inx] ) ) { - sprintf( message, "%ld", curFontSize ); - curInx = wListAddValue( list, message, NULL, (void*)curFontSize ); + wListClear(list); + for (inx = 0; inx < sizeof fontSizeList / sizeof fontSizeList[0]; inx++) + { + if ((inx == 0 || curFontSize > fontSizeList[inx - 1]) && + (curFontSize < fontSizeList[inx])) + { + sprintf(message, "%ld", curFontSize); + curInx = wListAddValue(list, message, NULL, (void*)curFontSize); } - sprintf( message, "%ld", fontSizeList[inx] ); - inx1 = wListAddValue( list, message, NULL, (void*)fontSizeList[inx] ); - if ( curFontSize == fontSizeList[inx] ) + sprintf(message, "%ld", fontSizeList[inx]); + inx1 = wListAddValue(list, message, NULL, (void*)fontSizeList[inx]); + if (curFontSize == fontSizeList[inx]) curInx = inx1; } - if ( curFontSize > fontSizeList[(sizeof fontSizeList/sizeof fontSizeList[0])-1] ) { - sprintf( message, "%ld", curFontSize ); - curInx = wListAddValue( list, message, NULL, (void*)curFontSize ); + if (curFontSize > fontSizeList[(sizeof fontSizeList / sizeof fontSizeList[0]) - 1]) + { + sprintf(message, "%ld", curFontSize); + curInx = wListAddValue(list, message, NULL, (void*)curFontSize); } - wListSetIndex( list, curInx ); + wListSetIndex(list, curInx); wFlush(); } +long GetFontSize(wIndex_t inx) +{ + return(fontSizeList[inx]); +} + +long GetFontSizeIndex(long size) +{ + int i; + for (i = 0; i < sizeof fontSizeList / sizeof fontSizeList[0]; i++) + { + if (fontSizeList[i] == size) + return(i); + } + return(-1); +} EXPORT void UpdateFontSizeList( long * fontSizeR, @@ -232,7 +250,8 @@ static void UpdateDraw( track_p trk, int inx, descData_p descUpd, BOOL_T final ) return; segPtr = &xx->segs[drawSegInx]; MainRedraw(); - //UndrawNewTrack( trk ); + MapRedraw(); + UndrawNewTrack( trk ); switch ( inx ) { case LW: segPtr->width = drawData.lineWidth/mainD.dpi; @@ -371,6 +390,7 @@ static void UpdateDraw( track_p trk, int inx, descData_p descUpd, BOOL_T final ) } ComputeDrawBoundingBox( trk ); DrawNewTrack( trk ); + DoCurCommand( C_REDRAW, zero ); } static void DescribeDraw( track_p trk, char * str, CSIZE_T len ) @@ -391,6 +411,7 @@ static void DescribeDraw( track_p trk, char * str, CSIZE_T len ) drawDesc[inx].control0 = NULL; } drawData.color = segPtr->color; + drawData.layer = GetTrkLayer(trk); drawDesc[CO].mode = 0; drawData.lineWidth = (long)floor(segPtr->width*mainD.dpi+0.5); drawDesc[LW].mode = 0; @@ -759,43 +780,10 @@ static drawContext_t drawCmdContext = { static void DrawRedraw( void ) { MainRedraw(); + MapRedraw(); } -#ifdef LATER -static void DrawOk( void * context ) -{ - track_p t; - struct extraData * xx; - trkSeg_p sp; - wIndex_t cnt; - - for ( cnt=0,sp=&DrawLineSegs(0); sp < &DrawLineSegs(drawCmdContext.Segs_da.cnt); sp++ ) - if (sp->type != ' ') - cnt++; - if (cnt == 0) - return; - UndoStart( _("Create Lines"), "newDraw" ); - for ( sp=&DrawLineSegs(0); sp < &DrawLineSegs(drawCmdContext.Segs_da.cnt); sp++ ) { - if (sp->type != ' ') { - t = NewTrack( 0, T_DRAW, 0, sizeof *xx + sizeof *(trkSeg_p)0 ); - xx = GetTrkExtraData( t ); - xx->orig = zero; - xx->angle = 0.0; - xx->segCnt = 1; - memcpy( xx->segs, sp, sizeof *(trkSeg_p)0 ); - ComputeDrawBoundingBox( t ); - DrawNewTrack(t); - } - } - UndoEnd(); - DYNARR_RESET( trkSeg_t, drawCmdContext.Segs_da ); - Reset(); -} -#endif - - - static wIndex_t benchChoice; static wIndex_t benchOrient; static wIndex_t dimArrowSize; @@ -914,10 +902,7 @@ static STATUS_T CmdDraw( wAction_t action, coOrd pos ) labels[2] = N_("Color"); if ( wListGetCount( (wList_p)drawBenchChoicePD.control ) == 0 ) BenchLoadLists( (wList_p)drawBenchChoicePD.control, (wList_p)drawBenchOrientPD.control ); -#ifdef LATER - if ( benchInx >= 0 && benchInx < wListGetCount( (wList_p)drawBenchChoicePD.control ) ) - wListSetIndex( (wList_p)drawBenchChoicePD.control, benchInx ); -#endif + ParamLoadControls( &drawPG ); BenchUpdateOrientationList( (long)wListGetItemContext( (wList_p)drawBenchChoicePD.control, benchChoice ), (wList_p)drawBenchOrientPD.control ); wListSetIndex( (wList_p)drawBenchOrientPD.control, benchOrient ); @@ -959,9 +944,7 @@ static STATUS_T CmdDraw( wAction_t action, coOrd pos ) if ( drawCmdContext.Op == OP_BENCH ) { drawCmdContext.benchOption = GetBenchData( (long)wListGetItemContext((wList_p)drawBenchChoicePD.control, benchChoice ), benchOrient ); drawCmdContext.Color = benchColor; -#ifdef LATER - benchInx = wListGetIndex( (wList_p)drawBenchChoicePD.control ); -#endif + } else if ( drawCmdContext.Op == OP_DIMLINE ) { drawCmdContext.benchOption = dimArrowSize; } else { @@ -1074,29 +1057,6 @@ static drawStuff_t drawStuff[4] = { { "cmdDrawShapeSetCmd", N_("Shapes"), N_("Draw Shapes"), 4, dshapeCmds} }; -#ifdef LATER -static void SetDrawMode( char * modeName ) -{ - wButton_p bb; - int inx1, inx2; - drawData_t * dp; - - for ( inx1=0; inx1<4; inx1++ ) { - for ( inx2=0; inx2<drawStuff[inx1].cnt; inx2++ ) { - dp = &drawStuff[inx1].data[inx2]; - if (strncmp( modeName, dp->modeS, strlen(dp->modeS) ) == 0 ) { - bb = GetCommandButton(drawStuff[inx1].cmdInx); - wButtonSetLabel( bb, (char*)(dp->icon) ); - wControlSetHelp( (wControl_p)bb, dp->help ); - drawStuff[inx1].curr = inx2; - DoCommandB( (void*)(drawStuff[inx1].cmdInx) ); - return; - } - } - } -} -#endif - static void ChangeDraw( long changes ) { diff --git a/app/bin/cmisc.c b/app/bin/cmisc.c index bb6e700..1e2ea39 100644 --- a/app/bin/cmisc.c +++ b/app/bin/cmisc.c @@ -153,6 +153,7 @@ static void DescribeUpdate( UndoStart( _("Change Track"), "Change Track" ); descUndoStarted = TRUE; } + if (!descTrk) return; // In case timer pops after OK UndoModify( descTrk ); descUpdateFunc( descTrk, ddp-descData, descData, FALSE ); if ( descTrk ) { diff --git a/app/bin/cmodify.c b/app/bin/cmodify.c index 89fd548..6828ff9 100644 --- a/app/bin/cmodify.c +++ b/app/bin/cmodify.c @@ -138,6 +138,7 @@ static STATUS_T CmdModify( } DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); MainRedraw(); + MapRedraw(); return rc; case C_MOVE: @@ -155,6 +156,7 @@ static STATUS_T CmdModify( } DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); MainRedraw(); + MapRedraw(); return rc; @@ -173,7 +175,7 @@ static STATUS_T CmdModify( //changeTrackMode = FALSE; Dex.Trk = NULL; MainRedraw(); - + MapRedraw(); return rc; case C_RDOWN: @@ -209,6 +211,7 @@ LOG( log_modify, 1, ("extend endPt[%d] = [%0.3f %0.3f] A%0.3f\n", } Dex.first = TRUE; MainRedraw(); + MapRedraw(); #ifdef LATER return C_CONTINUE; #endif @@ -327,6 +330,7 @@ LOG( log_modify, 2, ("A=%0.3f X=%0.3f\n", a0, Dex.jointD.x ) ) } DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack ); MainRedraw(); + MapRedraw(); return C_CONTINUE; case C_RUP: @@ -348,6 +352,7 @@ LOG( log_modify, 2, ("A=%0.3f X=%0.3f\n", a0, Dex.jointD.x ) ) UndoEnd(); DrawNewTrack(Dex.Trk ); MainRedraw(); + MapRedraw(); return C_TERMINATE; } trk = NewStraightTrack( Dex.pos01, Dex.curveData.pos1 ); @@ -373,6 +378,7 @@ LOG( log_modify, 1, ("A0 = %0.3f, A1 = %0.3f\n", DrawNewTrack( Dex.Trk ); Dex.Trk = NULL; MainRedraw(); + MapRedraw(); return C_TERMINATE; case C_REDRAW: diff --git a/app/bin/cprofile.c b/app/bin/cprofile.c index 99a3a6d..d8bbc24 100644 --- a/app/bin/cprofile.c +++ b/app/bin/cprofile.c @@ -716,6 +716,7 @@ static void DoProfileDone( void * junk ) wHide( profileW ); ClrAllTrkBits( TB_PROFILEPATH ); MainRedraw(); + MapRedraw(); #endif Reset(); } @@ -725,8 +726,10 @@ static void DoProfileClear( void * junk ) { profElem_da.cnt = 0; station_da.cnt = 0; - if (ClrAllTrkBits( TB_PROFILEPATH )) + if (ClrAllTrkBits( TB_PROFILEPATH )) { MainRedraw(); + MapRedraw(); + } pathStartTrk = pathEndTrk = NULL; RedrawProfileW(); } @@ -1277,8 +1280,10 @@ static STATUS_T CmdProfile( wAction_t action, coOrd pos ) profElem_da.cnt = 0; station_da.cnt = 0; RedrawProfileW(); - if ( ClrAllTrkBits( TB_PROFILEPATH ) ) + if ( ClrAllTrkBits( TB_PROFILEPATH ) ) { MainRedraw(); + MapRedraw(); + } pathStartTrk = NULL; SetAllTrackSelect( FALSE ); profileUndo = FALSE; @@ -1333,8 +1338,10 @@ static STATUS_T CmdProfile( wAction_t action, coOrd pos ) case C_CANCEL: wHide(profileW); HilightProfileElevations( FALSE ); - if (ClrAllTrkBits(TB_PROFILEPATH)) + if (ClrAllTrkBits(TB_PROFILEPATH)) { MainRedraw(); + MapRedraw(); + } return C_TERMINATE; case C_REDRAW: if ( wWinIsVisible(profileW) ) { diff --git a/app/bin/csensor.c b/app/bin/csensor.c new file mode 100644 index 0000000..e962089 --- /dev/null +++ b/app/bin/csensor.c @@ -0,0 +1,561 @@ +/** \file csensor.c + * Sensors + */ + +/* -*- C -*- **************************************************************** + * + * System : + * Module : + * Object Name : $RCSfile$ + * Revision : $Revision$ + * Date : $Date$ + * Author : $Author$ + * Created By : Robert Heller + * Created : Sun Mar 5 16:01:37 2017 + * Last Modified : <170314.1407> + * + * Description + * + * Notes + * + * History + * + **************************************************************************** + * + * Copyright (C) 2017 Robert Heller D/B/A Deepwoods Software + * 51 Locke Hill Road + * Wendell, MA 01379-9728 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * + ****************************************************************************/ + +static const char rcsid[] = "@(#) : $Id$"; + +#include <ctype.h> +#include "track.h" +#include "trackx.h" +#include "compound.h" +#include "i18n.h" + +EXPORT TRKTYP_T T_SENSOR = -1; + +static int log_sensor = 0; + + +#if 0 +static drawCmd_t sensorD = { + NULL, + &screenDrawFuncs, + 0, + 1.0, + 0.0, + {0.0,0.0}, {0.0,0.0}, + Pix2CoOrd, CoOrd2Pix }; + +static char sensorName[STR_SHORT_SIZE]; +static char sensorScript[STR_LONG_SIZE]; +#endif + +typedef struct sensorData_t { + coOrd orig; + BOOL_T IsHilite; + char * name; + char * script; +} sensorData_t, *sensorData_p; + +static sensorData_p GetsensorData ( track_p trk ) +{ + return (sensorData_p) GetTrkExtraData(trk); +} + +#define RADIUS 6 + +#define sensor_SF (3.0) + +static void DDrawSensor(drawCmd_p d, coOrd orig, DIST_T scaleRatio, + wDrawColor color ) +{ + coOrd p1, p2; + + p1 = orig; + DrawFillCircle(d,p1, RADIUS * sensor_SF / scaleRatio,color); + Translate (&p2, orig, 45, RADIUS * sensor_SF / scaleRatio); + DrawLine(d, p1, p2, 2, wDrawColorWhite); + Translate (&p2, orig, 45+90, RADIUS * sensor_SF / scaleRatio); + DrawLine(d, p1, p2, 2, wDrawColorWhite); + Translate (&p2, orig, 45+180, RADIUS * sensor_SF / scaleRatio); + DrawLine(d, p1, p2, 2, wDrawColorWhite); + Translate (&p2, orig, 45+270, RADIUS * sensor_SF / scaleRatio); + DrawLine(d, p1, p2, 2, wDrawColorWhite); +} + +static void DrawSensor (track_p t, drawCmd_p d, wDrawColor color ) +{ + sensorData_p xx = GetsensorData(t); + DDrawSensor(d,xx->orig,GetScaleRatio(GetTrkScale(t)),color); +} + +static void SensorBoundingBox (coOrd orig, DIST_T scaleRatio, coOrd *hi, + coOrd *lo) +{ + coOrd p1, p2; + + p1 = orig; + Translate (&p1, orig, 0, -RADIUS * sensor_SF / scaleRatio); + Translate (&p2, orig, 0, RADIUS * sensor_SF / scaleRatio); + *hi = p1; *lo = p1; + if (p2.x > hi->x) hi->x = p2.x; + if (p2.x < lo->x) lo->x = p2.x; + if (p2.y > hi->y) hi->y = p2.y; + if (p2.y < lo->y) lo->y = p2.y; +} + + +static void ComputeSensorBoundingBox (track_p t ) +{ + coOrd lo, hi; + sensorData_p xx = GetsensorData(t); + SensorBoundingBox(xx->orig, GetScaleRatio(GetTrkScale(t)), &hi, &lo); + SetBoundingBox(t, hi, lo); +} + +static DIST_T DistanceSensor (track_p t, coOrd * p ) +{ + sensorData_p xx = GetsensorData(t); + return FindDistance(xx->orig, *p); +} + +static struct { + char name[STR_SHORT_SIZE]; + coOrd pos; + char script[STR_LONG_SIZE]; +} sensorProperties; + +typedef enum { NM, PS, SC } sensorDesc_e; +static descData_t sensorDesc[] = { + /* NM */ { DESC_STRING, N_("Name"), &sensorProperties.name }, + /* PS */ { DESC_POS, N_("Position"), &sensorProperties.pos }, + /* SC */ { DESC_STRING, N_("Script"), &sensorProperties.script }, + { DESC_NULL } }; + +static void UpdateSensorProperties ( track_p trk, int inx, descData_p + descUpd, BOOL_T needUndoStart ) +{ + sensorData_p xx = GetsensorData(trk); + const char *thename, *thescript; + char *newName, *newScript; + BOOL_T changed, nChanged, pChanged, sChanged; + + switch (inx) { + case NM: + break; + case PS: + break; + case SC: + break; + case -1: + changed = nChanged = pChanged = sChanged = FALSE; + thename = wStringGetValue( (wString_p) sensorDesc[NM].control0 ); + if (strcmp(thename,xx->name) != 0) { + nChanged = changed = TRUE; + newName = MyStrdup(thename); + } + thescript = wStringGetValue( (wString_p) sensorDesc[SC].control0 ); + if (strcmp(thescript,xx->script) != 0) { + sChanged = changed = TRUE; + newScript = MyStrdup(thescript); + } + if (sensorProperties.pos.x != xx->orig.x || + sensorProperties.pos.y != xx->orig.y) { + pChanged = changed = TRUE; + } + if (!changed) break; + if (needUndoStart) + UndoStart( _("Change Sensor"), "Change Sensor" ); + UndoModify( trk ); + if (nChanged) { + MyFree(xx->name); + xx->name = newName; + } + if (pChanged) { + UndrawNewTrack( trk ); + } + if (pChanged) { + xx->orig = sensorProperties.pos; + } + if (sChanged) { + MyFree(xx->script); + xx->script = newScript; + } + if (pChanged) { + ComputeSensorBoundingBox( trk ); + DrawNewTrack( trk ); + } + break; + } +} + + + +static void DescribeSensor (track_p trk, char * str, CSIZE_T len ) +{ + sensorData_p xx = GetsensorData(trk); + + strcpy( str, _(GetTrkTypeName( trk )) ); + str++; + while (*str) { + *str = tolower((unsigned char)*str); + str++; + } + sprintf( str, _("(%d [%s]): Layer=%d, at %0.3f,%0.3f"), + GetTrkIndex(trk), + xx->name,GetTrkLayer(trk)+1, xx->orig.x, xx->orig.y); + strncpy(sensorProperties.name,xx->name,STR_SHORT_SIZE-1); + sensorProperties.name[STR_SHORT_SIZE-1] = '\0'; + strncpy(sensorProperties.script,xx->script,STR_LONG_SIZE-1); + sensorProperties.script[STR_LONG_SIZE-1] = '\0'; + sensorProperties.pos = xx->orig; + sensorDesc[NM].mode = + sensorDesc[SC].mode = DESC_NOREDRAW; + DoDescribe( _("Sensor"), trk, sensorDesc, UpdateSensorProperties ); +} + +static void DeleteSensor ( track_p trk ) +{ + sensorData_p xx = GetsensorData(trk); + MyFree(xx->name); xx->name = NULL; + MyFree(xx->script); xx->script = NULL; +} + +static BOOL_T WriteSensor ( track_p t, FILE * f ) +{ + BOOL_T rc = TRUE; + sensorData_p xx = GetsensorData(t); + rc &= fprintf(f, "SENSOR %d %d %s %d %0.6f %0.6f \"%s\" \"%s\"\n", + GetTrkIndex(t), GetTrkLayer(t), GetTrkScaleName(t), + GetTrkVisible(t), xx->orig.x, xx->orig.y, xx->name, + xx->script)>0; + return rc; +} + +static void ReadSensor ( char * line ) +{ + wIndex_t index; + /*TRKINX_T trkindex;*/ + track_p trk; + /*char * cp = NULL;*/ + char *name; + char *script; + coOrd orig; + BOOL_T visible; + char scale[10]; + wIndex_t layer; + sensorData_p xx; + if (!GetArgs(line+7,"dLsdpqq",&index,&layer,scale, &visible, &orig,&name,&script)) { + return; + } + trk = NewTrack(index, T_SENSOR, 0, sizeof(sensorData_t)); + SetTrkVisible(trk, visible); + SetTrkScale(trk, LookupScale( scale )); + SetTrkLayer(trk, layer); + xx = GetsensorData ( trk ); + xx->name = name; + xx->orig = orig; + xx->script = script; + ComputeSensorBoundingBox(trk); +} + +static void MoveSensor (track_p trk, coOrd orig ) +{ + sensorData_p xx = GetsensorData ( trk ); + xx->orig.x += orig.x; + xx->orig.y += orig.y; + ComputeSensorBoundingBox(trk); +} + +static void RotateSensor (track_p trk, coOrd orig, ANGLE_T angle ) +{ +} + +static void RescaleSensor (track_p trk, FLOAT_T ratio ) +{ +} + +static void FlipSensor (track_p trk, coOrd orig, ANGLE_T angle ) +{ + sensorData_p xx = GetsensorData ( trk ); + FlipPoint(&(xx->orig), orig, angle); + ComputeSensorBoundingBox(trk); +} + + +static trackCmd_t sensorCmds = { + "SENSOR", + DrawSensor, + DistanceSensor, + DescribeSensor, + DeleteSensor, + WriteSensor, + ReadSensor, + MoveSensor, + RotateSensor, + RescaleSensor, + NULL, /* audit */ + NULL, /* getAngle */ + NULL, /* split */ + NULL, /* traverse */ + NULL, /* enumerate */ + NULL, /* redraw */ + NULL, /* trim */ + NULL, /* merge */ + NULL, /* modify */ + NULL, /* getLength */ + NULL, /* getTrkParams */ + NULL, /* moveEndPt */ + NULL, /* query */ + NULL, /* ungroup */ + FlipSensor, /* flip */ + NULL, /* drawPositionIndicator */ + NULL, /* advancePositionIndicator */ + NULL, /* checkTraverse */ + NULL, /* makeParallel */ + NULL /* drawDesc */ +}; + +static coOrd sensorEditOrig; +static track_p sensorEditTrack; +static char sensorEditName[STR_SHORT_SIZE]; +static char sensorEditScript[STR_LONG_SIZE]; + +static paramFloatRange_t r_1000_1000 = { -1000.0, 1000.0, 80 }; +static paramData_t sensorEditPLs[] = { +#define I_SENSORNAME (0) + /*0*/ { PD_STRING, sensorEditName, "name", PDO_NOPREF, (void*)200, N_("Name") }, +#define I_ORIGX (1) + /*1*/ { PD_FLOAT, &sensorEditOrig.x, "origx", PDO_DIM, &r_1000_1000, N_("Orgin X") }, +#define I_ORIGY (2) + /*2*/ { PD_FLOAT, &sensorEditOrig.y, "origy", PDO_DIM, &r_1000_1000, N_("Origin Y") }, +#define I_SENSORSCRIPT (3) + /*3*/ { PD_STRING, sensorEditScript, "script", PDO_NOPREF, (void*)350, N_("Script") }, +}; + +static paramGroup_t sensorEditPG = { "sensorEdit", 0, sensorEditPLs, sizeof sensorEditPLs/sizeof sensorEditPLs[0] }; +static wWin_p sensorEditW; + +static void SensorEditOk ( void * junk ) +{ + track_p trk; + sensorData_p xx; + + if (sensorEditTrack == NULL) { + UndoStart( _("Create Sensor"), "Create Sensor"); + trk = NewTrack(0, T_SENSOR, 0, sizeof(sensorData_t)); + } else { + UndoStart( _("Modify Sensor"), "Modify Sensor"); + trk = sensorEditTrack; + } + xx = GetsensorData(trk); + xx->orig = sensorEditOrig; + if ( xx->name == NULL || strncmp (xx->name, sensorEditName, STR_SHORT_SIZE) != 0) { + MyFree(xx->name); + xx->name = MyStrdup(sensorEditName); + } + if ( xx->script == NULL || strncmp (xx->script, sensorEditScript, STR_LONG_SIZE) != 0) { + MyFree(xx->script); + xx->script = MyStrdup(sensorEditScript); + } + UndoEnd(); + DoRedraw(); + ComputeSensorBoundingBox(trk); + wHide( sensorEditW ); +} + +#if 0 +static void SensorEditCancel ( wWin_p junk ) +{ + wHide( sensorEditW ); +} +#endif + +static void EditSensorDialog() +{ + sensorData_p xx; + + if ( !sensorEditW ) { + ParamRegister( &sensorEditPG ); + sensorEditW = ParamCreateDialog (&sensorEditPG, + MakeWindowTitle(_("Edit sensor")), + _("Ok"), SensorEditOk, + wHide, TRUE, NULL, + F_BLOCK, + NULL ); + } + if (sensorEditTrack == NULL) { + sensorEditName[0] = '\0'; + sensorEditScript[0] = '\0'; + } else { + xx = GetsensorData ( sensorEditTrack ); + strncpy(sensorEditName,xx->name,STR_SHORT_SIZE); + strncpy(sensorEditScript,xx->script,STR_LONG_SIZE); + sensorEditOrig = xx->orig; + } + ParamLoadControls( &sensorEditPG ); + wShow( sensorEditW ); +} + +static void EditSensor (track_p trk) +{ + sensorEditTrack = trk; + EditSensorDialog(); +} + +static void CreateNewSensor (coOrd orig) +{ + sensorEditOrig = orig; + sensorEditTrack = NULL; + EditSensorDialog(); +} + +static STATUS_T CmdSensor ( wAction_t action, coOrd pos ) +{ + + + switch (action) { + case C_START: + InfoMessage(_("Place sensor")); + return C_CONTINUE; + case C_DOWN: + SnapPos(&pos); + DDrawSensor( &tempD, pos, GetScaleRatio(curScaleInx), wDrawColorBlack ); + return C_CONTINUE; + case C_MOVE: + SnapPos(&pos); + DDrawSensor( &tempD, pos, GetScaleRatio(curScaleInx), wDrawColorBlack ); + return C_CONTINUE; + case C_UP: + SnapPos(&pos); + DDrawSensor( &tempD, pos, GetScaleRatio(curScaleInx), wDrawColorBlack ); + CreateNewSensor(pos); + return C_TERMINATE; + case C_REDRAW: + case C_CANCEL: + DDrawSensor( &tempD, pos, GetScaleRatio(curScaleInx), wDrawColorBlack ); + return C_CONTINUE; + default: + return C_CONTINUE; + } +} + +static coOrd ctlhiliteOrig, ctlhiliteSize; +static POS_T ctlhiliteBorder; +static wDrawColor ctlhiliteColor = 0; +static void DrawSensorTrackHilite( void ) +{ + wPos_t x, y, w, h; + if (ctlhiliteColor==0) + ctlhiliteColor = wDrawColorGray(87); + w = (wPos_t)((ctlhiliteSize.x/mainD.scale)*mainD.dpi+0.5); + h = (wPos_t)((ctlhiliteSize.y/mainD.scale)*mainD.dpi+0.5); + mainD.CoOrd2Pix(&mainD,ctlhiliteOrig,&x,&y); + wDrawFilledRectangle( mainD.d, x, y, w, h, ctlhiliteColor, wDrawOptTemp ); +} + +static int SensorMgmProc ( int cmd, void * data ) +{ + track_p trk = (track_p) data; + sensorData_p xx = GetsensorData(trk); + /*char msg[STR_SIZE];*/ + + switch ( cmd ) { + case CONTMGM_CAN_EDIT: + return TRUE; + break; + case CONTMGM_DO_EDIT: + EditSensor(trk); + return TRUE; + break; + case CONTMGM_CAN_DELETE: + return TRUE; + break; + case CONTMGM_DO_DELETE: + DeleteTrack(trk, FALSE); + return TRUE; + break; + case CONTMGM_DO_HILIGHT: + if (!xx->IsHilite) { + ctlhiliteBorder = mainD.scale*0.1; + if ( ctlhiliteBorder < trackGauge ) ctlhiliteBorder = trackGauge; + GetBoundingBox( trk, &ctlhiliteSize, &ctlhiliteOrig ); + ctlhiliteOrig.x -= ctlhiliteBorder; + ctlhiliteOrig.y -= ctlhiliteBorder; + ctlhiliteSize.x -= ctlhiliteOrig.x-ctlhiliteBorder; + ctlhiliteSize.y -= ctlhiliteOrig.y-ctlhiliteBorder; + DrawSensorTrackHilite(); + xx->IsHilite = TRUE; + } + break; + case CONTMGM_UN_HILIGHT: + if (xx->IsHilite) { + ctlhiliteBorder = mainD.scale*0.1; + if ( ctlhiliteBorder < trackGauge ) ctlhiliteBorder = trackGauge; + GetBoundingBox( trk, &ctlhiliteSize, &ctlhiliteOrig ); + ctlhiliteOrig.x -= ctlhiliteBorder; + ctlhiliteOrig.y -= ctlhiliteBorder; + ctlhiliteSize.x -= ctlhiliteOrig.x-ctlhiliteBorder; + ctlhiliteSize.y -= ctlhiliteOrig.y-ctlhiliteBorder; + DrawSensorTrackHilite(); + xx->IsHilite = FALSE; + } + break; + case CONTMGM_GET_TITLE: + sprintf(message,"\t%s\t",xx->name); + break; + } + return FALSE; +} + +#include "bitmaps/sensor.xpm" + +EXPORT void SensorMgmLoad ( void ) +{ + track_p trk; + static wIcon_p sensorI = NULL; + + if (sensorI == NULL) { + sensorI = wIconCreatePixMap( sensor_xpm ); + } + + TRK_ITERATE(trk) { + if (GetTrkType(trk) != T_SENSOR) continue; + ContMgmLoad (sensorI, SensorMgmProc, (void *) trk ); + } +} + +#define ACCL_SENSOR 0 + +EXPORT void InitCmdSensor ( wMenu_p menu ) +{ + AddMenuButton( menu, CmdSensor, "cmdSensor", _("Sensor"), + wIconCreatePixMap( sensor_xpm ), LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_SENSOR, NULL ); +} + +EXPORT void InitTrkSensor ( void ) +{ + T_SENSOR = InitObject ( &sensorCmds ); + log_sensor = LogFindIndex ( "sensor" ); +} diff --git a/app/bin/csignal.c b/app/bin/csignal.c new file mode 100644 index 0000000..06adb19 --- /dev/null +++ b/app/bin/csignal.c @@ -0,0 +1,885 @@ +/** \file csignal.c + * Signals + */ + +/* -*- C -*- **************************************************************** + * + * System : + * Module : + * Object Name : $RCSfile$ + * Revision : $Revision$ + * Date : $Date$ + * Author : $Author$ + * Created By : Robert Heller + * Created : Sun Feb 19 13:11:45 2017 + * Last Modified : <170314.1311> + * + * Description + * + * Notes + * + * History + * + **************************************************************************** + * + * Copyright (C) 2017 Robert Heller D/B/A Deepwoods Software + * 51 Locke Hill Road + * Wendell, MA 01379-9728 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * + ****************************************************************************/ + +static const char rcsid[] = "@(#) : $Id$"; + + +#include <ctype.h> +#include "track.h" +#include "trackx.h" +#include "compound.h" +#include "i18n.h" + +EXPORT TRKTYP_T T_SIGNAL = -1; + +static int log_signal = 0; + + +#if 0 +static drawCmd_t signalD = { + NULL, + &screenDrawFuncs, + 0, + 1.0, + 0.0, + {0.0,0.0}, {0.0,0.0}, + Pix2CoOrd, CoOrd2Pix }; + +static char signalName[STR_SHORT_SIZE]; +static int signalHeadCount; +#endif + +typedef struct signalAspect_t { + char * aspectName; + char * aspectScript; +} signalAspect_t, *signalAspect_p; + +static dynArr_t signalAspect_da; +#define signalAspect(N) DYNARR_N( signalAspect_t, signalAspect_da, N ) + +typedef struct signalData_t { + coOrd orig; + ANGLE_T angle; + char * name; + wIndex_t numHeads; + BOOL_T IsHilite; + wIndex_t numAspects; + signalAspect_t aspectList; +} signalData_t, *signalData_p; + +static signalData_p GetsignalData ( track_p trk ) +{ + return (signalData_p) GetTrkExtraData(trk); +} + +#define BASEX 6 +#define BASEY 0 + +#define MASTX 0 +#define MASTY 12 + +#define HEADR 4 + + +#define signal_SF (3.0) + +static void DDrawSignal(drawCmd_p d, coOrd orig, ANGLE_T angle, + wIndex_t numHeads, DIST_T scaleRatio, + wDrawColor color ) +{ + coOrd p1, p2; + ANGLE_T x_angle, y_angle; + DIST_T hoffset; + wIndex_t ihead; + + x_angle = 90-(360-angle); + if (x_angle < 0) x_angle += 360; + y_angle = -(360-angle); + if (y_angle < 0) y_angle += 360; + + Translate (&p1, orig, x_angle, (-BASEX) * signal_SF / scaleRatio); + Translate (&p1, p1, y_angle, BASEY * signal_SF / scaleRatio); + Translate (&p2, orig, x_angle, BASEX * signal_SF / scaleRatio); + Translate (&p2, p2, y_angle, BASEY * signal_SF / scaleRatio); + DrawLine(d, p1, p2, 2, color); + p1 = orig; + Translate (&p2, orig, x_angle, MASTX * signal_SF / scaleRatio); + Translate (&p2, p2, y_angle, MASTY * signal_SF / scaleRatio); + DrawLine(d, p1, p2, 2, color); + hoffset = MASTY; + for (ihead = 0; ihead < numHeads; ihead++) { + Translate (&p1, orig, x_angle, MASTX * signal_SF / scaleRatio); + Translate (&p1, p1, y_angle, (hoffset+HEADR) * signal_SF / scaleRatio); + DrawFillCircle(d,p1,HEADR * signal_SF / scaleRatio,color); + hoffset += HEADR*2; + } +} + +static void DrawSignal (track_p t, drawCmd_p d, wDrawColor color ) +{ + signalData_p xx = GetsignalData(t); + DDrawSignal(d,xx->orig, xx->angle, xx->numHeads, GetScaleRatio(GetTrkScale(t)),color); +} + +static void SignalBoundingBox (coOrd orig, ANGLE_T angle,wIndex_t numHeads, + DIST_T scaleRatio, coOrd *hi, coOrd *lo) +{ + coOrd p1, p2, headp1, headp2; + ANGLE_T x_angle, y_angle; + DIST_T hoffset,delta; + wIndex_t ihead; + + x_angle = 90-(360-angle); + if (x_angle < 0) x_angle += 360; + y_angle = -(360-angle); + if (y_angle < 0) y_angle += 360; + + Translate (&p1, orig, x_angle, (-BASEX) * signal_SF / scaleRatio); + Translate (&p1, p1, y_angle, BASEY * signal_SF / scaleRatio); + Translate (&p2, orig, x_angle, BASEX * signal_SF / scaleRatio); + Translate (&p2, p2, y_angle, BASEY * signal_SF / scaleRatio); + *hi = p1; *lo = p1; + if (p2.x > hi->x) hi->x = p2.x; + if (p2.x < lo->x) lo->x = p2.x; + if (p2.y > hi->y) hi->y = p2.y; + if (p2.y < lo->y) lo->y = p2.y; + p1 = orig; + Translate (&p2, orig, x_angle, MASTX * signal_SF / scaleRatio); + Translate (&p2, p2, y_angle, MASTY * signal_SF / scaleRatio); + if (p1.x > hi->x) hi->x = p1.x; + if (p1.x < lo->x) lo->x = p1.x; + if (p1.y > hi->y) hi->y = p1.y; + if (p1.y < lo->y) lo->y = p1.y; + if (p2.x > hi->x) hi->x = p2.x; + if (p2.x < lo->x) lo->x = p2.x; + if (p2.y > hi->y) hi->y = p2.y; + if (p2.y < lo->y) lo->y = p2.y; + hoffset = MASTY; + for (ihead = 0; ihead < numHeads; ihead++) { + Translate (&p1, orig, x_angle, MASTX * signal_SF / scaleRatio); + Translate (&p1, p1, y_angle, (hoffset+HEADR) * signal_SF / scaleRatio); + delta = HEADR * signal_SF / scaleRatio; + headp1.x = p1.x - delta; + headp1.y = p1.y - delta; + headp2.x = p1.x + delta; + headp2.y = p1.y + delta; + if (headp1.x > hi->x) hi->x = headp1.x; + if (headp1.x < lo->x) lo->x = headp1.x; + if (headp1.y > hi->y) hi->y = headp1.y; + if (headp1.y < lo->y) lo->y = headp1.y; + if (headp2.x > hi->x) hi->x = headp2.x; + if (headp2.x < lo->x) lo->x = headp2.x; + if (headp2.y > hi->y) hi->y = headp2.y; + if (headp2.y < lo->y) lo->y = headp2.y; + hoffset += HEADR*2; + } + +} + +static void ComputeSignalBoundingBox (track_p t ) +{ + coOrd lo, hi; + signalData_p xx = GetsignalData(t); + SignalBoundingBox(xx->orig, xx->angle, xx->numHeads, + GetScaleRatio(GetTrkScale(t)), &hi, &lo); + SetBoundingBox(t, hi, lo); +} + +static DIST_T DistanceSignal (track_p t, coOrd * p ) +{ + signalData_p xx = GetsignalData(t); + return FindDistance(xx->orig, *p); +} + +static struct { + char name[STR_SHORT_SIZE]; + coOrd pos; + ANGLE_T orient; + long heads; +} signalProperties; + +typedef enum { NM, PS, OR, HD } signalDesc_e; +static descData_t signalDesc[] = { + /* NM */ { DESC_STRING, N_("Name"), &signalProperties.name }, + /* PS */ { DESC_POS, N_("Position"), &signalProperties.pos }, + /* OR */ { DESC_ANGLE, N_("Angle"), &signalProperties.orient }, + /* HD */ { DESC_LONG, N_("Number Of Heads"), &signalProperties.heads }, + { DESC_NULL } }; + +static void UpdateSignalProperties ( track_p trk, int inx, descData_p + descUpd, BOOL_T needUndoStart ) +{ + signalData_p xx = GetsignalData( trk ); + const char *thename; + char *newName; + BOOL_T changed, nChanged, pChanged, oChanged; + + switch (inx) { + case NM: break; + case PS: break; + case OR: break; + case HD: break; + case -1: + changed = nChanged = pChanged = oChanged = FALSE; + thename = wStringGetValue( (wString_p) signalDesc[NM].control0 ); + if (strcmp(thename,xx->name) != 0) { + nChanged = changed = TRUE; + newName = MyStrdup(thename); + } + if (signalProperties.pos.x != xx->orig.x || + signalProperties.pos.y != xx->orig.y) { + pChanged = changed = TRUE; + } + if (signalProperties.orient != xx->angle) { + oChanged = changed = TRUE; + } + if (!changed) break; + if (needUndoStart) + UndoStart( _("Change Signal"), "Change Signal" ); + UndoModify( trk ); + if (nChanged) { + MyFree(xx->name); + xx->name = newName; + } + if (pChanged || oChanged) { + UndrawNewTrack( trk ); + } + if (pChanged) { + xx->orig = signalProperties.pos; + } + if (oChanged) { + xx->angle = signalProperties.orient; + } + if (pChanged || oChanged) { + ComputeSignalBoundingBox( trk ); + DrawNewTrack( trk ); + } + break; + } +} + + +static void DescribeSignal (track_p trk, char * str, CSIZE_T len ) +{ + signalData_p xx = GetsignalData(trk); + + strcpy( str, _(GetTrkTypeName( trk )) ); + str++; + while (*str) { + *str = tolower((unsigned char)*str); + str++; + } + sprintf( str, _("(%d [%s]): Layer=%d, %d heads at %0.3f,%0.3f A%0.3f"), + GetTrkIndex(trk), + xx->name,GetTrkLayer(trk)+1, xx->numHeads, + xx->orig.x, xx->orig.y,xx->angle ); + strncpy(signalProperties.name,xx->name,STR_SHORT_SIZE-1); + signalProperties.name[STR_SHORT_SIZE-1] = '\0'; + signalProperties.pos = xx->orig; + signalProperties.orient = xx->angle; + signalProperties.heads = xx->numHeads; + signalDesc[HD].mode = DESC_RO; + signalDesc[NM].mode = DESC_NOREDRAW; + DoDescribe( _("Signal"), trk, signalDesc, UpdateSignalProperties ); +} + +static void DeleteSignal ( track_p trk ) +{ + wIndex_t ia; + signalData_p xx = GetsignalData(trk); + MyFree(xx->name); xx->name = NULL; + for (ia = 0; ia < xx->numAspects; ia++) { + MyFree((&(xx->aspectList))[ia].aspectName); + MyFree((&(xx->aspectList))[ia].aspectScript); + } +} + +static BOOL_T WriteSignal ( track_p t, FILE * f ) +{ + BOOL_T rc = TRUE; + wIndex_t ia; + signalData_p xx = GetsignalData(t); + rc &= fprintf(f, "SIGNAL %d %d %s %d %0.6f %0.6f %0.6f %d \"%s\"\n", + GetTrkIndex(t), GetTrkLayer(t), GetTrkScaleName(t), + GetTrkVisible(t), xx->orig.x, xx->orig.y, xx->angle, + xx->numHeads, xx->name)>0; + for (ia = 0; ia < xx->numAspects; ia++) { + rc &= fprintf(f, "\tASPECT \"%s\" \"%s\"\n", + (&(xx->aspectList))[ia].aspectName, + (&(xx->aspectList))[ia].aspectScript)>0; + } + rc &= fprintf( f, "\tEND\n" )>0; + return rc; +} + +static void ReadSignal ( char * line ) +{ + /*TRKINX_T trkindex;*/ + wIndex_t index; + track_p trk; + char * cp = NULL; + wIndex_t ia; + char *name; + char *aspname, *aspscript; + wIndex_t numHeads; + coOrd orig; + ANGLE_T angle; + BOOL_T visible; + char scale[10]; + wIndex_t layer; + signalData_p xx; + if (!GetArgs(line+6,"dLsdpfdq",&index,&layer,scale, &visible, &orig, + &angle, &numHeads,&name)) { + return; + } + DYNARR_RESET( signalAspect_p, signalAspect_da ); + while ( (cp = GetNextLine()) != NULL ) { + while (isspace((unsigned char)*cp)) cp++; + if ( strncmp( cp, "END", 3 ) == 0 ) { + break; + } + if ( *cp == '\n' || *cp == '#' ) { + continue; + } + if ( strncmp( cp, "ASPECT", 6 ) == 0 ) { + if (!GetArgs(cp+4,"qq",&aspname,&aspscript)) return; + DYNARR_APPEND( signalAspect_p *, signalAspect_da, 10 ); + signalAspect(signalAspect_da.cnt-1).aspectName = aspname; + signalAspect(signalAspect_da.cnt-1).aspectScript = aspscript; + } + } + trk = NewTrack(index, T_SIGNAL, 0, sizeof(signalData_t)+(sizeof(signalAspect_t)*(signalAspect_da.cnt-1))+1); + SetTrkVisible(trk, visible); + SetTrkScale(trk, LookupScale( scale )); + SetTrkLayer(trk, layer); + xx = GetsignalData ( trk ); + xx->name = name; + xx->numHeads = numHeads; + xx->orig = orig; + xx->angle = angle; + xx->numAspects = signalAspect_da.cnt; + for (ia = 0; ia < xx->numAspects; ia++) { + (&(xx->aspectList))[ia].aspectName = signalAspect(ia).aspectName; + (&(xx->aspectList))[ia].aspectScript = signalAspect(ia).aspectScript; + } + ComputeSignalBoundingBox(trk); +} + +static void MoveSignal (track_p trk, coOrd orig ) +{ + signalData_p xx = GetsignalData ( trk ); + xx->orig.x += orig.x; + xx->orig.y += orig.y; + ComputeSignalBoundingBox(trk); +} + +static void RotateSignal (track_p trk, coOrd orig, ANGLE_T angle ) +{ + signalData_p xx = GetsignalData ( trk ); + Rotate(&(xx->orig), orig, angle); + xx->angle = NormalizeAngle(xx->angle + angle); + ComputeSignalBoundingBox(trk); +} + +static void RescaleSignal (track_p trk, FLOAT_T ratio ) +{ +} + +static void FlipSignal (track_p trk, coOrd orig, ANGLE_T angle ) +{ + signalData_p xx = GetsignalData ( trk ); + FlipPoint(&(xx->orig), orig, angle); + xx->angle = NormalizeAngle(2*angle - xx->angle); + ComputeSignalBoundingBox(trk); +} + +static trackCmd_t signalCmds = { + "SIGNAL", + DrawSignal, + DistanceSignal, + DescribeSignal, + DeleteSignal, + WriteSignal, + ReadSignal, + MoveSignal, + RotateSignal, + RescaleSignal, + NULL, /* audit */ + NULL, /* getAngle */ + NULL, /* split */ + NULL, /* traverse */ + NULL, /* enumerate */ + NULL, /* redraw */ + NULL, /* trim */ + NULL, /* merge */ + NULL, /* modify */ + NULL, /* getLength */ + NULL, /* getTrkParams */ + NULL, /* moveEndPt */ + NULL, /* query */ + NULL, /* ungroup */ + FlipSignal, /* flip */ + NULL, /* drawPositionIndicator */ + NULL, /* advancePositionIndicator */ + NULL, /* checkTraverse */ + NULL, /* makeParallel */ + NULL /* drawDesc */ +}; + +static BOOL_T signalCreate_P; +static coOrd signalEditOrig; +static ANGLE_T signalEditAngle; +static track_p signalEditTrack; + +static char signalEditName[STR_SHORT_SIZE]; +static long signalEditHeadCount; +static char signalAspectEditName[STR_SHORT_SIZE]; +static char signalAspectEditScript[STR_LONG_SIZE]; +static long signalAspectEditIndex; + +static paramIntegerRange_t r1_3 = {1, 3}; +static wPos_t aspectListWidths[] = { STR_SHORT_SIZE, 150 }; +static const char * aspectListTitles[] = { N_("Name"), N_("Script") }; +static paramListData_t aspectListData = {10, 400, 2, aspectListWidths, aspectListTitles}; + +static void AspectEdit( void * action ); +static void AspectAdd( void * action ); +static void AspectDelete( void * action ); + +static paramFloatRange_t r_1000_1000 = { -1000.0, 1000.0, 80 }; +static paramFloatRange_t r0_360 = { 0.0, 360.0, 80 }; +static paramData_t signalEditPLs[] = { +#define I_SIGNALNAME (0) + /*0*/ { PD_STRING, signalEditName, "name", PDO_NOPREF, (void*)200, N_("Name") }, +#define I_ORIGX (1) + /*1*/ { PD_FLOAT, &signalEditOrig.x, "origx", PDO_DIM, &r_1000_1000, N_("Orgin X") }, +#define I_ORIGY (2) + /*2*/ { PD_FLOAT, &signalEditOrig.y, "origy", PDO_DIM, &r_1000_1000, N_("Origin Y") }, +#define I_ANGLE (3) + /*3*/ { PD_FLOAT, &signalEditAngle, "origa", PDO_ANGLE, &r0_360, N_("Angle") }, +#define I_SIGNALHEADCOUNT (4) + /*4*/ { PD_LONG, &signalEditHeadCount, "headCount", PDO_NOPREF, &r1_3, N_("Number of Heads") }, +#define I_SIGNALASPECTLIST (5) +#define aspectSelL ((wList_p)signalEditPLs[I_SIGNALASPECTLIST].control) + /*5*/ { PD_LIST, NULL, "inx", PDO_DLGRESETMARGIN|PDO_DLGRESIZE, &aspectListData, NULL, BL_MANY }, +#define I_SIGNALASPECTEDIT (6) + /*6*/ { PD_BUTTON, (void*)AspectEdit, "edit", PDO_DLGCMDBUTTON, NULL, N_("Edit Aspect") }, +#define I_SIGNALASPECTADD (7) + /*7*/ { PD_BUTTON, (void*)AspectAdd, "add", PDO_DLGCMDBUTTON, NULL, N_("Add Aspect") }, +#define I_SIGNALASPECTDELETE (8) + /*8*/ { PD_BUTTON, (void*)AspectDelete, "delete", 0, NULL, N_("Delete Aspect") }, +}; +static paramGroup_t signalEditPG = { "signalEdit", 0, signalEditPLs, sizeof signalEditPLs/sizeof signalEditPLs[0] }; +static wWin_p signalEditW; + +static paramIntegerRange_t rm1_999999 = { -1, 999999 }; + +static paramData_t aspectEditPLs[] = { +#define I_ASPECTNAME (0) + /*0*/ { PD_STRING, signalAspectEditName, "name", PDO_NOPREF, (void*)200, N_("Name") }, +#define I_ASPECTSCRIPT (1) + /*1*/ { PD_STRING, signalAspectEditScript, "script", PDO_NOPREF, (void*)350, N_("Script") }, +#define I_ASPECTINDEX (2) + /*2*/ { PD_LONG, &signalAspectEditIndex, "index", PDO_NOPREF, &rm1_999999, N_("Aspect Index"), BO_READONLY }, +}; + +static paramGroup_t aspectEditPG = { "aspectEdit", 0, aspectEditPLs, sizeof aspectEditPLs/sizeof aspectEditPLs[0] }; +static wWin_p aspectEditW; + + +static void SignalEditOk ( void * junk ) +{ + track_p trk; + signalData_p xx; + wIndex_t ia; + + if (signalCreate_P) { + UndoStart( _("Create Signal"), "Create Signal"); + trk = NewTrack(0, T_SIGNAL, 0, sizeof(signalData_t)+(sizeof(signalAspect_t)*(signalAspect_da.cnt-1))+1); + xx = GetsignalData(trk); + } else { + UndoStart( _("Modify Signal"), "Modify Signal"); + trk = signalEditTrack; + xx = GetsignalData(trk); + if (xx->numAspects != signalAspect_da.cnt) { + /* We need to reallocate the extra data. */ + /* We will delete the Signal and re-create it. */ + BOOL_T visible = GetTrkVisible(trk); + SCALEINX_T scale = GetTrkScale(trk); + LAYER_T layer = GetTrkLayer(trk); + wIndex_t tindx = GetTrkIndex(trk); + FreeTrack(trk); + trk = NewTrack(tindx, T_SIGNAL, 0, sizeof(signalData_t)+(sizeof(signalAspect_t)*(signalAspect_da.cnt-1))+1); + SetTrkVisible(trk,visible); + SetTrkScale(trk,scale); + SetTrkLayer(trk,layer); + xx = GetsignalData(trk); + } + } + xx->orig = signalEditOrig; + xx->angle = signalEditAngle; + xx->numHeads = signalEditHeadCount; + if ( xx->name == NULL || strncmp (xx->name, signalEditName, STR_SHORT_SIZE) != 0) { + MyFree(xx->name); + xx->name = MyStrdup(signalEditName); + } + xx->numAspects = signalAspect_da.cnt; + for (ia = 0; ia < xx->numAspects; ia++) { + if ((&(xx->aspectList))[ia].aspectName == NULL) { + (&(xx->aspectList))[ia].aspectName = signalAspect(ia).aspectName; + } else if (strcmp((&(xx->aspectList))[ia].aspectName,signalAspect(ia).aspectName) != 0) { + MyFree((&(xx->aspectList))[ia].aspectName); + (&(xx->aspectList))[ia].aspectName = signalAspect(ia).aspectName; + } else { + MyFree(signalAspect(ia).aspectName); + } + if ((&(xx->aspectList))[ia].aspectScript == NULL) { + (&(xx->aspectList))[ia].aspectScript = signalAspect(ia).aspectScript; + } else if (strcmp((&(xx->aspectList))[ia].aspectScript,signalAspect(ia).aspectScript) != 0) { + MyFree((&(xx->aspectList))[ia].aspectScript); + (&(xx->aspectList))[ia].aspectScript = signalAspect(ia).aspectScript; + } else { + MyFree(signalAspect(ia).aspectScript); + } + } + UndoEnd(); + DoRedraw(); + ComputeSignalBoundingBox(trk); + wHide( signalEditW ); +} + +static void SignalEditCancel ( wWin_p junk ) +{ + wIndex_t ia; + + for (ia = 0; ia < signalAspect_da.cnt; ia++) { + MyFree(signalAspect(ia).aspectName); + MyFree(signalAspect(ia).aspectScript); + } + DYNARR_RESET( signalAspect_p, signalAspect_da ); + wHide( signalEditW ); +} + +static void SignalEditDlgUpdate (paramGroup_p pg, int inx, void *valueP ) +{ + wIndex_t selcnt = wListGetSelectedCount( aspectSelL ); + + if ( inx != I_SIGNALASPECTLIST ) return; + ParamControlActive( &signalEditPG, I_SIGNALASPECTEDIT, selcnt>0 ); + ParamControlActive( &signalEditPG, I_SIGNALASPECTADD, TRUE ); + ParamControlActive( &signalEditPG, I_SIGNALASPECTDELETE, selcnt>0 ); +} + +static void aspectEditOK ( void * junk ) +{ + if (signalAspectEditIndex < 0) { + DYNARR_APPEND( signalAspect_p *, signalAspect_da, 10 ); + signalAspect(signalAspect_da.cnt-1).aspectName = MyStrdup(signalAspectEditName); + signalAspect(signalAspect_da.cnt-1).aspectScript = MyStrdup(signalAspectEditScript); + snprintf(message,sizeof(message),"%s\t%s",signalAspectEditName,signalAspectEditScript); + wListAddValue( aspectSelL, message, NULL, NULL ); + } else { + if ( strncmp( signalAspectEditName, signalAspect(signalAspectEditIndex).aspectName,STR_SHORT_SIZE ) != 0 ) { + MyFree(signalAspect(signalAspectEditIndex).aspectName); + signalAspect(signalAspectEditIndex).aspectName = MyStrdup(signalAspectEditName); + } + if ( strncmp( signalAspectEditScript, signalAspect(signalAspectEditIndex).aspectScript, STR_LONG_SIZE ) != 0 ) { + MyFree(signalAspect(signalAspectEditIndex).aspectScript); + signalAspect(signalAspectEditIndex).aspectScript = MyStrdup(signalAspectEditScript); + } + snprintf(message,sizeof(message),"%s\t%s",signalAspect(signalAspectEditIndex).aspectName,signalAspect(signalAspectEditIndex).aspectScript); + wListSetValues( aspectSelL, signalAspectEditIndex, message, NULL, NULL ); + } + wHide( aspectEditW ); +} + +static void EditAspectDialog ( wIndex_t inx ) +{ + if (inx < 0) { + signalAspectEditName[0] = '\0'; + signalAspectEditScript[0] = '\0'; + } else { + strncpy(signalAspectEditName,signalAspect(inx).aspectName,STR_SHORT_SIZE); + strncpy(signalAspectEditScript,signalAspect(inx).aspectScript,STR_LONG_SIZE); + } + signalAspectEditIndex = inx; + if ( !aspectEditW ) { + ParamRegister( &aspectEditPG ); + aspectEditW = ParamCreateDialog (&aspectEditPG, + MakeWindowTitle(_("Edit aspect")), + _("Ok"), aspectEditOK, + wHide, TRUE, NULL,F_BLOCK,NULL); + } + ParamLoadControls( &aspectEditPG ); + wShow( aspectEditW ); +} + +static void AspectEdit( void * action ) +{ + wIndex_t selcnt = wListGetSelectedCount( aspectSelL ); + wIndex_t inx, cnt; + + if ( selcnt != 1) return; + cnt = wListGetCount( aspectSelL ); + for ( inx=0; + inx<cnt && wListGetItemSelected( aspectSelL, inx ) != TRUE; + inx++ ); + if ( inx >= cnt ) return; + EditAspectDialog(inx); +} + +static void AspectAdd( void * action ) +{ + EditAspectDialog(-1); +} + +static void MoveAspectUp (wIndex_t inx) +{ + wIndex_t cnt = signalAspect_da.cnt; + wIndex_t ia; + + MyFree(signalAspect(inx).aspectName); + MyFree(signalAspect(inx).aspectScript); + for (ia = inx+1; ia < cnt; ia++) { + signalAspect(ia-1).aspectName = signalAspect(ia).aspectName; + signalAspect(ia-1).aspectScript = signalAspect(ia).aspectScript; + } + DYNARR_SET(signalAspect_t,signalAspect_da,cnt-1); +} + +static void AspectDelete( void * action ) +{ + wIndex_t selcnt = wListGetSelectedCount( aspectSelL ); + wIndex_t inx, cnt; + + if ( selcnt <= 0) return; + if ( (!NoticeMessage2( 1, _("Are you sure you want to delete the %d aspect(s)"), _("Yes"), _("No"), selcnt ) ) ) + return; + cnt = wListGetCount( aspectSelL ); + for ( inx=0; inx<cnt; inx++ ) { + if ( !wListGetItemSelected( aspectSelL, inx ) ) continue; + wListDelete( aspectSelL, inx ); + MoveAspectUp(inx); + inx--; + cnt--; + } + DoChangeNotification( CHANGE_PARAMS ); +} + +static void EditSignalDialog() +{ + signalData_p xx; + wIndex_t ia; + + if ( !signalEditW ) { + ParamRegister( &signalEditPG ); + signalEditW = ParamCreateDialog (&signalEditPG, + MakeWindowTitle(_("Edit signal")), + _("Ok"), SignalEditOk, + SignalEditCancel, TRUE, NULL, + F_RESIZE|F_RECALLSIZE|F_BLOCK, + SignalEditDlgUpdate ); + } + if (signalCreate_P) { + signalEditName[0] = '\0'; + signalEditHeadCount = 1; + wListClear( aspectSelL ); + DYNARR_RESET( signalAspect_p, signalAspect_da ); + } else { + xx = GetsignalData ( signalEditTrack ); + strncpy(signalEditName,xx->name,STR_SHORT_SIZE); + signalEditHeadCount = xx->numHeads; + signalEditOrig = xx->orig; + signalEditAngle = xx->angle; + wListClear( aspectSelL ); + DYNARR_RESET( signalAspect_p, signalAspect_da ); + for (ia = 0; ia < xx->numAspects; ia++) { + snprintf(message,sizeof(message),"%s\t%s",(&(xx->aspectList))[ia].aspectName, + (&(xx->aspectList))[ia].aspectScript); + wListAddValue( aspectSelL, message, NULL, NULL ); + DYNARR_APPEND( signalAspect_p *, signalAspect_da, 10 ); + signalAspect(signalAspect_da.cnt-1).aspectName = MyStrdup((&(xx->aspectList))[ia].aspectName); + signalAspect(signalAspect_da.cnt-1).aspectScript = MyStrdup((&(xx->aspectList))[ia].aspectScript); + } + } + ParamLoadControls( &signalEditPG ); + ParamControlActive( &signalEditPG, I_SIGNALASPECTEDIT, FALSE ); + ParamControlActive( &signalEditPG, I_SIGNALASPECTADD, TRUE ); + ParamControlActive( &signalEditPG, I_SIGNALASPECTDELETE, FALSE ); + wShow( signalEditW ); +} + + + + +static void EditSignal (track_p trk) +{ + signalCreate_P = FALSE; + signalEditTrack = trk; + EditSignalDialog(); +} + +static void CreateNewSignal (coOrd orig, ANGLE_T angle) +{ + signalCreate_P = TRUE; + signalEditOrig = orig; + signalEditAngle = angle; + EditSignalDialog(); +} + +static coOrd pos0; +static ANGLE_T orient; + +static STATUS_T CmdSignal ( wAction_t action, coOrd pos ) +{ + + + switch (action) { + case C_START: + InfoMessage(_("Place base of signal")); + return C_CONTINUE; + case C_DOWN: + SnapPos(&pos); + pos0 = pos; + InfoMessage(_("Drag to orient signal")); + return C_CONTINUE; + case C_MOVE: + SnapPos(&pos); + orient = FindAngle(pos0,pos); + DDrawSignal( &tempD, pos0, orient, 1, GetScaleRatio(curScaleInx), wDrawColorBlack ); + return C_CONTINUE; + case C_UP: + SnapPos(&pos); + orient = FindAngle(pos0,pos); + CreateNewSignal(pos0,orient); + return C_TERMINATE; + case C_REDRAW: + case C_CANCEL: + DDrawSignal( &tempD, pos0, orient, 1, GetScaleRatio(curScaleInx), wDrawColorBlack ); + return C_CONTINUE; + default: + return C_CONTINUE; + } +} + +static coOrd sighiliteOrig, sighiliteSize; +static POS_T sighiliteBorder; +static wDrawColor sighiliteColor = 0; +static void DrawSignalTrackHilite( void ) +{ + wPos_t x, y, w, h; + if (sighiliteColor==0) + sighiliteColor = wDrawColorGray(87); + w = (wPos_t)((sighiliteSize.x/mainD.scale)*mainD.dpi+0.5); + h = (wPos_t)((sighiliteSize.y/mainD.scale)*mainD.dpi+0.5); + mainD.CoOrd2Pix(&mainD,sighiliteOrig,&x,&y); + wDrawFilledRectangle( mainD.d, x, y, w, h, sighiliteColor, wDrawOptTemp ); +} + +static int SignalMgmProc ( int cmd, void * data ) +{ + track_p trk = (track_p) data; + signalData_p xx = GetsignalData(trk); + /*char msg[STR_SIZE];*/ + + switch ( cmd ) { + case CONTMGM_CAN_EDIT: + return TRUE; + break; + case CONTMGM_DO_EDIT: + EditSignal(trk); + return TRUE; + break; + case CONTMGM_CAN_DELETE: + return TRUE; + break; + case CONTMGM_DO_DELETE: + DeleteTrack(trk, FALSE); + return TRUE; + break; + case CONTMGM_DO_HILIGHT: + if (!xx->IsHilite) { + sighiliteBorder = mainD.scale*0.1; + if ( sighiliteBorder < trackGauge ) sighiliteBorder = trackGauge; + GetBoundingBox( trk, &sighiliteSize, &sighiliteOrig ); + sighiliteOrig.x -= sighiliteBorder; + sighiliteOrig.y -= sighiliteBorder; + sighiliteSize.x -= sighiliteOrig.x-sighiliteBorder; + sighiliteSize.y -= sighiliteOrig.y-sighiliteBorder; + DrawSignalTrackHilite(); + xx->IsHilite = TRUE; + } + break; + case CONTMGM_UN_HILIGHT: + if (xx->IsHilite) { + sighiliteBorder = mainD.scale*0.1; + if ( sighiliteBorder < trackGauge ) sighiliteBorder = trackGauge; + GetBoundingBox( trk, &sighiliteSize, &sighiliteOrig ); + sighiliteOrig.x -= sighiliteBorder; + sighiliteOrig.y -= sighiliteBorder; + sighiliteSize.x -= sighiliteOrig.x-sighiliteBorder; + sighiliteSize.y -= sighiliteOrig.y-sighiliteBorder; + DrawSignalTrackHilite(); + xx->IsHilite = FALSE; + } + break; + case CONTMGM_GET_TITLE: + sprintf(message,"\t%s\t",xx->name); + break; + } + return FALSE; +} + +#include "bitmaps/signal.xpm" + +EXPORT void SignalMgmLoad ( void ) +{ + track_p trk; + static wIcon_p signalI = NULL; + + if (signalI == NULL) { + signalI = wIconCreatePixMap( signal_xpm ); + } + + TRK_ITERATE(trk) { + if (GetTrkType(trk) != T_SIGNAL) continue; + ContMgmLoad (signalI, SignalMgmProc, (void *) trk ); + } +} + +#define ACCL_SIGNAL 0 + +EXPORT void InitCmdSignal ( wMenu_p menu ) +{ + AddMenuButton( menu, CmdSignal, "cmdSignal", _("Signal"), + wIconCreatePixMap( signal_xpm ), LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_SIGNAL, NULL ); +} + +EXPORT void InitTrkSignal ( void ) +{ + T_SIGNAL = InitObject ( &signalCmds ); + log_signal = LogFindIndex ( "signal" ); +} diff --git a/app/bin/cswitchmotor.c b/app/bin/cswitchmotor.c index 7b948a8..dbe006c 100644 --- a/app/bin/cswitchmotor.c +++ b/app/bin/cswitchmotor.c @@ -1,6 +1,8 @@ /** \file cswitchmotor.c * Switch Motors - * Created by Robert Heller on Sat Mar 14 10:39:56 2009 + */ + +/* Created by Robert Heller on Sat Mar 14 10:39:56 2009 * ------------------------------------------------------------------ * Modification History: $Log: not supported by cvs2svn $ * Modification History: Revision 1.5 2009/11/23 19:46:16 rheller @@ -49,16 +51,15 @@ #include <ctype.h> #include "track.h" +#include "trackx.h" #include "compound.h" #include "i18n.h" EXPORT TRKTYP_T T_SWITCHMOTOR = -1; -#define SWITCHMOTORCMD - static int log_switchmotor = 0; -#ifdef SWITCHMOTORCMD + static drawCmd_t switchmotorD = { NULL, &screenDrawFuncs, @@ -82,19 +83,41 @@ static paramData_t switchmotorPLs[] = { }; static paramGroup_t switchmotorPG = { "switchmotor", 0, switchmotorPLs, sizeof switchmotorPLs/sizeof switchmotorPLs[0] }; +static wWin_p switchmotorW; + +static char switchmotorEditName[STR_SHORT_SIZE]; +static char switchmotorEditNormal[STR_LONG_SIZE]; +static char switchmotorEditReverse[STR_LONG_SIZE]; +static char switchmotorEditPointSense[STR_LONG_SIZE]; +static long int switchmotorEditTonum; +static track_p switchmotorEditTrack; + +static paramIntegerRange_t r0_999999 = { 0, 999999 }; + +static paramData_t switchmotorEditPLs[] = { +/*0*/ { PD_STRING, switchmotorEditName, "name", PDO_NOPREF, (void*)200, N_("Name") }, +/*1*/ { PD_STRING, switchmotorEditNormal, "normal", PDO_NOPREF, (void*)350, N_("Normal") }, +/*2*/ { PD_STRING, switchmotorEditReverse, "reverse", PDO_NOPREF, (void*)350, N_("Reverse") }, +/*3*/ { PD_STRING, switchmotorEditPointSense, "pointSense", PDO_NOPREF, (void*)350, N_("Point Sense") }, +/*4*/ { PD_LONG, &switchmotorEditTonum, "turnoutNumber", PDO_NOPREF, &r0_999999, N_("Turnout Number"), BO_READONLY }, +}; + +static paramGroup_t switchmotorEditPG = { "switchmotorEdit", 0, switchmotorEditPLs, sizeof switchmotorEditPLs/sizeof switchmotorEditPLs[0] }; +static wWin_p switchmotorEditW; + /* static dynArr_t switchmotorTrk_da; #define switchmotorTrk(N) DYNARR_N( track_p , switchmotorTrk_da, N ) */ -static wWin_p switchmotorW; -#endif typedef struct switchmotorData_t { - char * name; - char * normal; - char * reverse; - char * pointsense; - track_p turnout; + char * name; + char * normal; + char * reverse; + char * pointsense; + BOOL_T IsHilite; + TRKINX_T turnindx; + track_p turnout; } switchmotorData_t, *switchmotorData_p; static switchmotorData_p GetswitchmotorData ( track_p trk ) @@ -102,27 +125,75 @@ static switchmotorData_p GetswitchmotorData ( track_p trk ) return (switchmotorData_p) GetTrkExtraData(trk); } +#if 0 #include "bitmaps/switchmotormark.xbm" static wDrawBitMap_p switchmotormark_bm = NULL; +#endif + +static coOrd switchmotorPoly_Pix[] = { + {6,0}, {6,13}, {4,13}, {4,19}, {6,19}, {6,23}, {9,23}, {9,19}, {13,19}, + {13,23}, {27,23}, {27,10}, {13,10}, {13,13}, {9,13}, {9,0}, {6,0} }; +#define switchmotorPoly_CNT (sizeof(switchmotorPoly_Pix)/sizeof(switchmotorPoly_Pix[0])) +#define switchmotorPoly_SF (3.0) +static void ComputeSwitchMotorBoundingBox (track_p t) +{ + coOrd hi, lo, p; + switchmotorData_p data_p = GetswitchmotorData(t); + struct extraData *xx = GetTrkExtraData(data_p->turnout); + coOrd orig = xx->orig; + ANGLE_T angle = xx->angle; + SCALEINX_T s = GetTrkScale(data_p->turnout); + DIST_T scaleRatio = GetScaleRatio(s); + int iPoint; + ANGLE_T x_angle, y_angle; + + x_angle = 90-(360-angle); + if (x_angle < 0) x_angle += 360; + y_angle = -(360-angle); + if (y_angle < 0) y_angle += 360; + + + for (iPoint = 0; iPoint < switchmotorPoly_CNT; iPoint++) { + Translate (&p, orig, x_angle, switchmotorPoly_Pix[iPoint].x * switchmotorPoly_SF / scaleRatio ); + Translate (&p, p, y_angle, (10+switchmotorPoly_Pix[iPoint].y) * switchmotorPoly_SF / scaleRatio ); + if (iPoint == 0) { + lo = p; + hi = p; + } else { + if (p.x < lo.x) lo.x = p.x; + if (p.y < lo.y) lo.y = p.y; + if (p.x > hi.x) hi.x = p.x; + if (p.y > hi.y) hi.y = p.y; + } + } + SetBoundingBox(t, hi, lo); +} + + static void DrawSwitchMotor (track_p t, drawCmd_p d, wDrawColor color ) { - coOrd p; - switchmotorData_p data_p = GetswitchmotorData(t); - struct extraData *xx = GetTrkExtraData(data_p->turnout); - coOrd orig = xx->orig; - ANGLE_T angle = xx->angle; - - if (switchmotormark_bm == NULL) { - switchmotormark_bm = - wDrawBitMapCreate( mainD.d, - switchmotormark_width, - switchmotormark_height, 16, 16, - switchmotormark_bits); - } - Translate (&p, orig, -angle , 2 ); - Translate (&p, p, 90-angle, 2); - DrawBitMap(d, p, switchmotormark_bm, color); + coOrd p[switchmotorPoly_CNT]; + switchmotorData_p data_p = GetswitchmotorData(t); + struct extraData *xx = GetTrkExtraData(data_p->turnout); + coOrd orig = xx->orig; + ANGLE_T angle = xx->angle; + SCALEINX_T s = GetTrkScale(data_p->turnout); + DIST_T scaleRatio = GetScaleRatio(s); + int iPoint; + ANGLE_T x_angle, y_angle; + + x_angle = 90-(360-angle); + if (x_angle < 0) x_angle += 360; + y_angle = -(360-angle); + if (y_angle < 0) y_angle += 360; + + + for (iPoint = 0; iPoint < switchmotorPoly_CNT; iPoint++) { + Translate (&p[iPoint], orig, x_angle, switchmotorPoly_Pix[iPoint].x * switchmotorPoly_SF / scaleRatio ); + Translate (&p[iPoint], p[iPoint], y_angle, (10+switchmotorPoly_Pix[iPoint].y) * switchmotorPoly_SF / scaleRatio ); + } + DrawFillPoly(d, switchmotorPoly_CNT, p, wDrawColorBlack); } static struct { @@ -199,6 +270,7 @@ static void UpdateSwitchMotor (track_p trk, int inx, descData_p descUpd, BOOL_T static DIST_T DistanceSwitchMotor (track_p t, coOrd * p ) { switchmotorData_p xx = GetswitchmotorData(t); + if (xx->turnout == NULL) return 0; return GetTrkDistance(xx->turnout,*p); } @@ -227,7 +299,8 @@ static void DescribeSwitchMotor (track_p trk, char * str, CSIZE_T len ) switchmotorData.reverse[STR_LONG_SIZE-1] = '\0'; strncpy(switchmotorData.pointsense,xx->pointsense,STR_LONG_SIZE-1); switchmotorData.pointsense[STR_LONG_SIZE-1] = '\0'; - switchmotorData.turnout = GetTrkIndex(xx->turnout); + if (xx->turnout == NULL) switchmotorData.turnout = 0; + else switchmotorData.turnout = GetTrkIndex(xx->turnout); switchmotorDesc[TO].mode = DESC_RO; switchmotorDesc[NM].mode = switchmotorDesc[NOR].mode = @@ -245,13 +318,20 @@ static void switchmotorDebug (track_p trk) LOG( log_switchmotor, 1, ("*** switchmotorDebug(): normal = \"%s\"\n",xx->normal)) LOG( log_switchmotor, 1, ("*** switchmotorDebug(): reverse = \"%s\"\n",xx->reverse)) LOG( log_switchmotor, 1, ("*** switchmotorDebug(): pointsense = \"%s\"\n",xx->pointsense)) - LOG( log_switchmotor, 1, ("*** switchmotorDebug(): turnout = T%d, %s\n", - GetTrkIndex(xx->turnout), GetTrkTypeName(xx->turnout))) + LOG( log_switchmotor, 1, ("*** switchmotorDebug(): turnindx = %d\n",xx->turnindx)) + if (xx->turnout != NULL) { + LOG( log_switchmotor, 1, ("*** switchmotorDebug(): turnout = T%d, %s\n", + GetTrkIndex(xx->turnout), GetTrkTypeName(xx->turnout))) + } } static void DeleteSwitchMotor ( track_p trk ) { - switchmotorData_p xx = GetswitchmotorData(trk); + LOG( log_switchmotor, 1,("*** DeleteSwitchMotor(%p)\n",trk)) + LOG( log_switchmotor, 1,("*** DeleteSwitchMotor(): index is %d\n",GetTrkIndex(trk))) + switchmotorData_p xx = GetswitchmotorData(trk); + LOG( log_switchmotor, 1,("*** DeleteSwitchMotor(): xx = %p, xx->name = %p, xx->normal = %p, xx->reverse = %p, xx->pointsense = %p\n", + xx,xx->name,xx->normal,xx->reverse,xx->pointsense)) MyFree(xx->name); xx->name = NULL; MyFree(xx->normal); xx->normal = NULL; MyFree(xx->reverse); xx->reverse = NULL; @@ -262,7 +342,8 @@ static BOOL_T WriteSwitchMotor ( track_p t, FILE * f ) { BOOL_T rc = TRUE; switchmotorData_p xx = GetswitchmotorData(t); - + + if (xx->turnout == NULL) return FALSE; rc &= fprintf(f, "SWITCHMOTOR %d %d \"%s\" \"%s\" \"%s\" \"%s\"\n", GetTrkIndex(t), GetTrkIndex(xx->turnout), xx->name, xx->normal, xx->reverse, xx->pointsense)>0; @@ -287,8 +368,28 @@ static void ReadSwitchMotor ( char * line ) xx->normal = normal; xx->reverse = reverse; xx->pointsense = pointsense; - xx->turnout = FindTrack(trkindex); - switchmotorDebug(trk); + xx->turnindx = trkindex; + LOG( log_switchmotor, 1,("*** ReadSwitchMotor(): trk = %p (%d), xx = %p\n",trk,GetTrkIndex(trk),xx)) + LOG( log_switchmotor, 1,("*** ReadSwitchMotor(): name = %p, normal = %p, reverse = %p, pointsense = %p\n", + name,normal,reverse,pointsense)) + switchmotorDebug(trk); +} + +EXPORT void ResolveSwitchmotorTurnout ( track_p trk ) +{ + LOG( log_switchmotor, 1,("*** ResolveSwitchmotorTurnout(%p)\n",trk)) + switchmotorData_p xx; + track_p t_trk; + if (GetTrkType(trk) != T_SWITCHMOTOR) return; + xx = GetswitchmotorData(trk); + LOG( log_switchmotor, 1, ("*** ResolveSwitchmotorTurnout(%d)\n",GetTrkIndex(trk))) + t_trk = FindTrack(xx->turnindx); + if (t_trk == NULL) { + NoticeMessage( _("ResolveSwitchmotor: Turnout T%d: T%d doesn't exist"), _("Continue"), NULL, GetTrkIndex(trk), xx->turnindx ); + } + xx->turnout = t_trk; + ComputeSwitchMotorBoundingBox(trk); + LOG( log_switchmotor, 1,("*** ResolveSwitchmotorTurnout(): t_trk = (%d) %p\n",xx->turnindx,t_trk)) } static void MoveSwitchMotor (track_p trk, coOrd orig ) {} @@ -329,7 +430,6 @@ static trackCmd_t switchmotorCmds = { NULL /* drawDesc */ }; -#ifdef SWITCHMOTORCMD static track_p FindSwitchMotor (track_p trk) { track_p a_trk; @@ -352,7 +452,7 @@ static void SwitchMotorOk ( void * junk ) LOG( log_switchmotor, 1, ("*** SwitchMotorOk()\n")) ParamUpdate (&switchmotorPG ); if ( switchmotorName[0]==0 ) { - NoticeMessage( 0, "Switch motor must have a name!", _("Ok")); + NoticeMessage( _("Switch motor must have a name!"), _("Ok"), NULL); return; } wDrawDelayUpdate( mainD.d, TRUE ); @@ -365,9 +465,12 @@ static void SwitchMotorOk ( void * junk ) xx->reverse = MyStrdup(switchmotorReverse); xx->pointsense = MyStrdup(switchmotorPointSense); xx->turnout = switchmotorTurnout; + LOG( log_switchmotor, 1,("*** SwitchMotorOk(): trk = %p (%d), xx = %p\n",trk,GetTrkIndex(trk),xx)) switchmotorDebug(trk); UndoEnd(); - wHide( switchmotorW ); + wHide( switchmotorW ); + ComputeSwitchMotorBoundingBox(trk); + DrawNewTrack(trk); } static void NewSwitchMotorDialog(track_p trk) @@ -413,6 +516,7 @@ static STATUS_T CmdSwitchMotorCreate( wAction_t action, coOrd pos ) } } +#if 0 extern BOOL_T inDescribeCmd; static STATUS_T CmdSwitchMotorEdit( wAction_t action, coOrd pos ) @@ -501,27 +605,177 @@ static STATUS_T CmdSwitchMotor (wAction_t action, coOrd pos ) default: return C_TERMINATE; } } +#endif + +static void SwitchMotorEditOk ( void * junk ) +{ + switchmotorData_p xx; + track_p trk; + + LOG( log_switchmotor, 1, ("*** SwitchMotorEditOk()\n")) + ParamUpdate (&switchmotorEditPG ); + if ( switchmotorEditName[0]==0 ) { + NoticeMessage( _("Switch motor must have a name!") , _("Ok"), NULL); + return; + } + wDrawDelayUpdate( mainD.d, TRUE ); + UndoStart( _("Modify Switch Motor"), "Modify Switch Motor" ); + trk = switchmotorEditTrack; + xx = GetswitchmotorData( trk ); + xx->name = MyStrdup(switchmotorEditName); + xx->normal = MyStrdup(switchmotorEditNormal); + xx->reverse = MyStrdup(switchmotorEditReverse); + xx->pointsense = MyStrdup(switchmotorEditPointSense); + switchmotorDebug(trk); + UndoEnd(); + wHide( switchmotorEditW ); +} + + +static void EditSwitchMotor (track_p trk) +{ + switchmotorData_p xx = GetswitchmotorData(trk); + strncpy(switchmotorEditName,xx->name,STR_SHORT_SIZE); + strncpy(switchmotorEditNormal,xx->normal,STR_LONG_SIZE); + strncpy(switchmotorEditReverse,xx->reverse,STR_LONG_SIZE); + strncpy(switchmotorEditPointSense,xx->pointsense,STR_LONG_SIZE); + if (xx->turnout == NULL) switchmotorEditTonum = 0; + else switchmotorEditTonum = GetTrkIndex(xx->turnout); + switchmotorEditTrack = trk; + if ( !switchmotorEditW ) { + ParamRegister( &switchmotorEditPG ); + switchmotorEditW = ParamCreateDialog (&switchmotorEditPG, + MakeWindowTitle(_("Edit switch motor")), + _("Ok"), SwitchMotorEditOk, + wHide, TRUE, NULL, F_BLOCK, + NULL ); + } + ParamLoadControls( &switchmotorEditPG ); + sprintf( message, _("Edit switch motor %d"), GetTrkIndex(trk) ); + wWinSetTitle( switchmotorEditW, message ); + wShow (switchmotorEditW); +} + +static coOrd swmhiliteOrig, swmhiliteSize; +static POS_T swmhiliteBorder; +static wDrawColor swmhiliteColor = 0; +static void DrawSWMotorTrackHilite( void ) +{ + wPos_t x, y, w, h; + if (swmhiliteColor==0) + swmhiliteColor = wDrawColorGray(87); + w = (wPos_t)((swmhiliteSize.x/mainD.scale)*mainD.dpi+0.5); + h = (wPos_t)((swmhiliteSize.y/mainD.scale)*mainD.dpi+0.5); + mainD.CoOrd2Pix(&mainD,swmhiliteOrig,&x,&y); + wDrawFilledRectangle( mainD.d, x, y, w, h, swmhiliteColor, wDrawOptTemp ); +} + +static int SwitchmotorMgmProc ( int cmd, void * data ) +{ + track_p trk = (track_p) data; + switchmotorData_p xx = GetswitchmotorData(trk); + /*char msg[STR_SIZE];*/ + + switch ( cmd ) { + case CONTMGM_CAN_EDIT: + return TRUE; + break; + case CONTMGM_DO_EDIT: + EditSwitchMotor (trk); + /*inDescribeCmd = TRUE;*/ + /*DescribeTrack (trk, msg, sizeof msg );*/ + /*InfoMessage( msg );*/ + return TRUE; + break; + case CONTMGM_CAN_DELETE: + return TRUE; + break; + case CONTMGM_DO_DELETE: + DeleteTrack (trk, FALSE); + return TRUE; + break; + case CONTMGM_DO_HILIGHT: + if (xx->turnout != NULL && !xx->IsHilite) { + swmhiliteBorder = mainD.scale*0.1; + if ( swmhiliteBorder < trackGauge ) swmhiliteBorder = trackGauge; + GetBoundingBox( xx->turnout, &swmhiliteSize, &swmhiliteOrig ); + swmhiliteOrig.x -= swmhiliteBorder; + swmhiliteOrig.y -= swmhiliteBorder; + swmhiliteSize.x -= swmhiliteOrig.x-swmhiliteBorder; + swmhiliteSize.y -= swmhiliteOrig.y-swmhiliteBorder; + DrawSWMotorTrackHilite(); + xx->IsHilite = TRUE; + } + break; + case CONTMGM_UN_HILIGHT: + if (xx->turnout != NULL && xx->IsHilite) { + swmhiliteBorder = mainD.scale*0.1; + if ( swmhiliteBorder < trackGauge ) swmhiliteBorder = trackGauge; + GetBoundingBox( xx->turnout, &swmhiliteSize, &swmhiliteOrig ); + swmhiliteOrig.x -= swmhiliteBorder; + swmhiliteOrig.y -= swmhiliteBorder; + swmhiliteSize.x -= swmhiliteOrig.x-swmhiliteBorder; + swmhiliteSize.y -= swmhiliteOrig.y-swmhiliteBorder; + DrawSWMotorTrackHilite(); + xx->IsHilite = FALSE; + } + break; + case CONTMGM_GET_TITLE: + if (xx->turnout == NULL) { + sprintf( message, "\t%s\t%d", xx->name, 0); + } else { + sprintf( message, "\t%s\t%d", xx->name, GetTrkIndex(xx->turnout)); + } + break; + } + return FALSE; +} //#include "bitmaps/switchmotor.xpm" -#include "bitmaps/switchmnew.xpm" -#include "bitmaps/switchmedit.xpm" -#include "bitmaps/switchmdel.xpm" +//#include "bitmaps/switchmnew.xpm" +//#include "bitmaps/switchmedit.xpm" +//#include "bitmaps/switchmdel.xpm" +#include "bitmaps/switchm.xpm" + +EXPORT void SwitchmotorMgmLoad( void ) +{ + track_p trk; + static wIcon_p switchmI = NULL; + + if ( switchmI == NULL) + switchmI = wIconCreatePixMap( switchm_xpm ); + + TRK_ITERATE(trk) { + if (GetTrkType(trk) != T_SWITCHMOTOR) continue; + ContMgmLoad( switchmI, SwitchmotorMgmProc, (void *)trk ); + } +} EXPORT void InitCmdSwitchMotor( wMenu_p menu ) { switchmotorName[0] = '\0'; switchmotorNormal[0] = '\0'; switchmotorReverse[0] = '\0'; - switchmotorPointSense[0] = '\0'; - ButtonGroupBegin( _("SwitchMotor"), "cmdSwitchMotorSetCmd", _("Switch Motors") ); - AddMenuButton( menu, CmdSwitchMotor, "cmdSwitchMotorCreate", _("Create Switch Motor"), wIconCreatePixMap(switchmnew_xpm), LEVEL0_50, IC_CANCEL|IC_POPUP, ACCL_SWITCHMOTOR1, (void*)SWITCHMOTOR_CREATE ); - AddMenuButton( menu, CmdSwitchMotor, "cmdSwitchMotorEdit", _("Edit Switch Motor"), wIconCreatePixMap(switchmedit_xpm), LEVEL0_50, IC_CANCEL|IC_POPUP, ACCL_SWITCHMOTOR2, (void*)SWITCHMOTOR_EDIT ); - AddMenuButton( menu, CmdSwitchMotor, "cmdSwitchMotorDelete", _("Delete Switch Motor"), wIconCreatePixMap(switchmdel_xpm), LEVEL0_50, IC_CANCEL|IC_POPUP, ACCL_SWITCHMOTOR3, (void*)SWITCHMOTOR_DELETE ); - ButtonGroupEnd(); + switchmotorPointSense[0] = '\0'; + AddMenuButton( menu, CmdSwitchMotorCreate, "cmdSwitchMotorCreate", + _("Switch Motor"), wIconCreatePixMap( switchm_xpm ), + LEVEL0_50, IC_STICKY|IC_POPUP2, ACCL_SWITCHMOTOR1, + NULL ); ParamRegister( &switchmotorPG ); } -#endif +EXPORT void CheckDeleteSwitchmotor(track_p t) +{ + track_p sm; + switchmotorData_p xx; + + sm = FindSwitchMotor( t ); + if (sm == NULL) return; + xx = GetswitchmotorData (sm); + NoticeMessage(_("Deleting Switch Motor %s"),_("Ok"),NULL,xx->name); + DeleteTrack (sm, FALSE); +} + EXPORT void InitTrkSwitchMotor( void ) diff --git a/app/bin/ctext.c b/app/bin/ctext.c index 0779ef5..525b55a 100644 --- a/app/bin/ctext.c +++ b/app/bin/ctext.c @@ -1,7 +1,5 @@ -/* - * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/bin/ctext.c,v 1.4 2008-03-06 19:35:06 m_fischer Exp $ - * - * TEXT +/** \file ctext.c + * Text command * */ @@ -26,11 +24,12 @@ #include "track.h" #include "i18n.h" - track_p NewText( wIndex_t index, coOrd p, ANGLE_T angle, char * text, CSIZE_T textSize, wDrawColor color ); void LoadFontSizeList( wList_p, long ); void UpdateFontSizeList( long *, wList_p, wIndex_t ); +long GetFontSize(long); +long GetFontSizeIndex(long size); static wMenu_p textPopupM; @@ -60,6 +59,11 @@ static paramData_t textPLs[] = { }; static paramGroup_t textPG = { "text", 0, textPLs, sizeof textPLs/sizeof textPLs[0] }; +enum TEXT_POSITION +{ + POSITION_TEXT = 0, + SHOW_TEXT +}; static void TextDlgUpdate( paramGroup_p pg, @@ -70,20 +74,20 @@ static void TextDlgUpdate( switch (inx) { case 0: - if ( Dt.state == 1 ) { + if ( Dt.state == SHOW_TEXT) { DrawString( &tempD, Dt.pos, 0.0, Dt.text, NULL, (FONTSIZE_T)Dt.size, Dt.color ); DrawLine( &tempD, Dt.cursPos0, Dt.cursPos1, 0, Dt.color ); } UpdateFontSizeList( &Dt.size, (wList_p)textPLs[0].control, Dt.fontSizeInx ); /*wWinSetBusy( mainW, TRUE );*/ - if ( Dt.state == 1 ) { + if ( Dt.state == SHOW_TEXT) { DrawTextSize( &mainD, Dt.text, NULL, Dt.size, TRUE, &size ); Dt.textLen = size.x; } DrawTextSize( &mainD, "X", NULL, Dt.size, TRUE, &size ); Dt.cursHeight = size.y; /*wWinSetBusy( mainW, FALSE );*/ - if ( Dt.state == 1 ) { + if ( Dt.state == SHOW_TEXT) { Dt.cursPos0.x = Dt.cursPos1.x = Dt.pos.x+Dt.textLen; Dt.cursPos1.y = Dt.pos.y+Dt.cursHeight; DrawLine( &tempD, Dt.cursPos0, Dt.cursPos1, 0, Dt.color ); @@ -105,24 +109,31 @@ static STATUS_T CmdText( wAction_t action, coOrd pos ) switch (action & 0xFF) { case C_START: - /* check if font size was updated by the preferences dialog */ - Dt.size = (CSIZE_T)wSelectedFontSize(); - Dt.state = 0; + Dt.state = POSITION_TEXT; Dt.cursPos0 = Dt.cursPos1 = zero; Dt.len = 0; Dt.textLen = 0; Dt.text[0] = '\0'; - if ( !inPlayback ) - wWinSetBusy( mainW, TRUE ); - DrawTextSize( &mainD, "X", NULL, Dt.size, TRUE, &size ); - Dt.cursHeight = size.y; - if ( !inPlayback ) - wWinSetBusy( mainW, FALSE ); - if ( textPD.control==NULL ) { - ParamCreateControls( &textPG, TextDlgUpdate ); + + if (textPD.control == NULL) + { + ParamCreateControls(&textPG, TextDlgUpdate); + LoadFontSizeList((wList_p)textPD.control, Dt.size); + ParamRegister(&textPG); + Dt.size = GetFontSize(Dt.fontSizeInx); } - LoadFontSizeList( (wList_p)textPD.control, Dt.size ); + Dt.size = wSelectedFontSize(); + Dt.fontSizeInx = GetFontSizeIndex(Dt.size); + ParamLoadControls(&textPG); ParamGroupRecord( &textPG ); + + if (!inPlayback) + wWinSetBusy(mainW, TRUE); + DrawTextSize(&mainD, "X", NULL, Dt.size, TRUE, &size); + Dt.cursHeight = size.y; + if (!inPlayback) + wWinSetBusy(mainW, FALSE); + controls[0] = textPD.control; controls[1] = colorPD.control; controls[2] = 0; @@ -142,7 +153,7 @@ static STATUS_T CmdText( wAction_t action, coOrd pos ) Dt.cursPos1.y += Dt.cursHeight; DrawLine( &tempD, Dt.cursPos0, Dt.cursPos1, 0, Dt.color ); DrawString( &tempD, Dt.pos, 0.0, Dt.text, NULL, (FONTSIZE_T)Dt.size, Dt.color ); - Dt.state = 1; + Dt.state = SHOW_TEXT; MainRedraw(); return C_CONTINUE; case C_MOVE: @@ -159,14 +170,13 @@ static STATUS_T CmdText( wAction_t action, coOrd pos ) case C_UP: return C_CONTINUE; case C_TEXT: - if (Dt.state == 0) { + if (Dt.state == POSITION_TEXT) { NoticeMessage( MSG_SEL_POS_FIRST, _("Ok"), NULL ); return C_CONTINUE; } DrawLine( &tempD, Dt.cursPos0, Dt.cursPos1, 0, Dt.color ); DrawString( &tempD, Dt.pos, 0.0, Dt.text, NULL, (FONTSIZE_T)Dt.size, Dt.color ); c = (unsigned char)(action >> 8); -/*lprintf("C=%x\n", c);*/ switch (c) { case '\b': case 0xFF: @@ -182,7 +192,7 @@ static STATUS_T CmdText( wAction_t action, coOrd pos ) t = NewText( 0, Dt.pos, Dt.angle, Dt.text, (CSIZE_T)Dt.size, Dt.color ); UndoEnd(); DrawNewTrack(t); - Dt.state = 0; + Dt.state = POSITION_TEXT; InfoSubstituteControls( NULL, NULL ); return C_TERMINATE; default: @@ -204,18 +214,18 @@ static STATUS_T CmdText( wAction_t action, coOrd pos ) } return C_CONTINUE; case C_CANCEL: - if (Dt.state != 0) { + if (Dt.state != POSITION_TEXT) { //DrawString( &tempD, Dt.pos, 0.0, Dt.text, NULL, (FONTSIZE_T)Dt.size, Dt.color ); //DrawLine( &tempD, Dt.cursPos0, Dt.cursPos1, 0, Dt.color ); - Dt.state = 0; + Dt.state = POSITION_TEXT; } InfoSubstituteControls( NULL, NULL ); MainRedraw(); return C_TERMINATE; case C_OK: - if (Dt.state != 0) { + if (Dt.state != POSITION_TEXT) { DrawLine( &tempD, Dt.cursPos0, Dt.cursPos1, 0, Dt.color ); - Dt.state = 0; + Dt.state = POSITION_TEXT; if (Dt.len) { UndoStart( _("Create Text"), "newText - OK" ); t = NewText( 0, Dt.pos, Dt.angle, Dt.text, (CSIZE_T)Dt.size, Dt.color ); @@ -228,7 +238,7 @@ static STATUS_T CmdText( wAction_t action, coOrd pos ) return C_TERMINATE; case C_FINISH: - if (Dt.state != 0 && Dt.len > 0) + if (Dt.state != POSITION_TEXT && Dt.len > 0) CmdText( C_OK, pos ); else CmdText( C_CANCEL, pos ); @@ -251,7 +261,6 @@ void InitCmdText( wMenu_p menu ) wMenuPushCreate( textPopupM, "", _("Fonts..."), 0, (wMenuCallBack_p)SelectFont, NULL ); Dt.size = (CSIZE_T)wSelectedFontSize(); Dt.color = wDrawColorBlack; - ParamRegister( &textPG ); } void InitTrkText( void ) diff --git a/app/bin/cundo.c b/app/bin/cundo.c index 1d17503..13d7af0 100644 --- a/app/bin/cundo.c +++ b/app/bin/cundo.c @@ -507,7 +507,7 @@ static track_p * FindParent( track_p trk, int lineNum ) { track_p *ptrk; ptrk = &to_first; - while ( 1 ) { + while ( 1 ) { if ( *ptrk == trk ) return ptrk; if (*ptrk == NULL) diff --git a/app/bin/custom.c b/app/bin/custom.c index cbde60b..766dbd8 100644 --- a/app/bin/custom.c +++ b/app/bin/custom.c @@ -135,7 +135,10 @@ BOOL_T Initialize( void ) InitTrkDraw(); InitTrkNote(); InitTrkBlock(); - InitTrkSwitchMotor(); + InitTrkSwitchMotor(); + InitTrkSignal(); + InitTrkControl(); + InitTrkSensor(); InitCarDlg(); memset( message, 0, sizeof message ); diff --git a/app/bin/custom.h b/app/bin/custom.h index 3987c16..b8ab213 100644 --- a/app/bin/custom.h +++ b/app/bin/custom.h @@ -94,6 +94,9 @@ void InitTrkTurnout( void ); void InitTrkTurntable( void ); void InitTrkBlock( void ); void InitTrkSwitchMotor( void ); +void InitTrkSignal ( void ); +void InitTrkControl ( void ); +void InitTrkSensor ( void ); void InitCmdCurve( wMenu_p menu ); void InitCmdHelix( wMenu_p menu ); diff --git a/app/bin/dcontmgm.c b/app/bin/dcontmgm.c new file mode 100644 index 0000000..45fec89 --- /dev/null +++ b/app/bin/dcontmgm.c @@ -0,0 +1,312 @@ +/** \file dcontmgm.c + * Manage layout control elements + */ + +/* -*- C -*- **************************************************************** + * + * System : + * Module : + * Created By : Robert Heller + * Created : Thu Jan 5 10:52:12 2017 + * Last Modified : <170411.1447> + * + * Description + * + * Control Element Mangment. Control Elements are elements related to + * layout control: Blocks (occupency detection), Switchmotors (actuators + * to "throw" turnouts), and (eventually) signals. These elements don't + * relate to "physical" items on the layout, but instead refer to the + * elements used by the layout control software. These elements contain + * "scripts", which are really just textual items that provide information + * for the layout control software and provide a bridge between physical + * layout elements (like tracks or turnouts) and the layout control + * software. These textual items could be actual software code or could + * be LCC Events (for I/O device elements on a LCC network) or DCC + * addresses for stationary decoders, etc. XTrkCAD does not impose any + * sort of syntax or format -- that is left up to other software that might + * load and parse the XTrkCAD layout file. All the XTrkCAD does is provide + * a unified place for this information to be stored and to provide a + * mapping (association) between this control information and the layout + * itself. + * + * + * Notes + * + * History + * + **************************************************************************** + * + * Copyright (C) 2017 Robert Heller D/B/A Deepwoods Software + * 51 Locke Hill Road + * Wendell, MA 01379-9728 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * + ****************************************************************************/ + +static const char rcsid[] = "@(#) : $Id$"; + + + +#include "track.h" +#include <errno.h> +#include "i18n.h" + +#ifdef WINDOWS +#include <io.h> +#define F_OK (0) +#define W_OK (2) +#define access _access +#endif + +/***************************************************************************** + * + * Control List Management + * + */ + +static void ControlEdit( void * action ); +static void ControlDelete( void * action ); +static void ControlDone( void * action ); +static wPos_t controlListWidths[] = { 18, 100, 150 }; +static const char * controlListTitles[] = { "", N_("Name"), + N_("Tracks") }; +static paramListData_t controlListData = { 10, 400, 3, controlListWidths, controlListTitles }; +static paramData_t controlPLs[] = { +#define I_CONTROLLIST (0) +#define controlSelL ((wList_p)controlPLs[I_CONTROLLIST].control) + { PD_LIST, NULL, "inx", PDO_DLGRESETMARGIN|PDO_DLGRESIZE, &controlListData, NULL, BL_MANY }, +#define I_CONTROLEDIT (1) + { PD_BUTTON, (void*)ControlEdit, "edit", PDO_DLGCMDBUTTON, NULL, N_("Edit") }, +#define I_CONTROLDEL (2) + { PD_BUTTON, (void*)ControlDelete, "delete", 0, NULL, N_("Delete") }, + } ; +static paramGroup_t controlPG = { "contmgm", 0, controlPLs, sizeof controlPLs/sizeof controlPLs[0] }; + + +typedef struct { + contMgmCallBack_p proc; + void * data; + wIcon_p icon; + } contMgmContext_t, *contMgmContext_p; + +static BOOL_T AnyHILIGHT = FALSE; + +static void ControlDlgUpdate( + paramGroup_p pg, + int inx, + void *valueP ) +{ + contMgmContext_p context = NULL; + wIndex_t selcnt = wListGetSelectedCount( (wList_p)controlPLs[0].control ); + wIndex_t linx, lcnt; + + if ( inx != I_CONTROLLIST ) return; + lcnt = wListGetCount( (wList_p)controlPLs[0].control ); + AnyHILIGHT = FALSE; + for (linx=0; + linx < lcnt; + linx++ ) { + if (wListGetItemSelected( (wList_p)controlPLs[0].control, linx ) == TRUE) { + context = (contMgmContext_p)wListGetItemContext( controlSelL, linx ); + context->proc( CONTMGM_DO_HILIGHT, context->data ); + AnyHILIGHT = TRUE; + } else { + context = (contMgmContext_p)wListGetItemContext( controlSelL, linx ); + context->proc( CONTMGM_UN_HILIGHT, context->data ); + } + } + ParamControlActive( &controlPG, I_CONTROLEDIT, selcnt>0 ); + ParamControlActive( &controlPG, I_CONTROLDEL, selcnt>0 ); +} + +static void ControlEdit( void * action ) +{ + contMgmContext_p context = NULL; + wIndex_t selcnt = wListGetSelectedCount( (wList_p)controlPLs[0].control ); + wIndex_t inx, cnt; + + if ( selcnt != 1 ) + return; + cnt = wListGetCount( (wList_p)controlPLs[0].control ); + for ( inx=0; + inx<cnt && wListGetItemSelected( (wList_p)controlPLs[0].control, inx ) != TRUE; + inx++ ); + if ( inx >= cnt ) + return; + context = (contMgmContext_p)wListGetItemContext( controlSelL, inx ); + if ( context == NULL ) + return; + context->proc( CONTMGM_DO_EDIT, context->data ); + context->proc( CONTMGM_GET_TITLE, context->data ); + wListSetValues( controlSelL, inx, message, context->icon, context ); +} + + +static void ControlDelete( void * action ) +{ + wIndex_t selcnt = wListGetSelectedCount( (wList_p)controlPLs[0].control ); + wIndex_t inx, cnt; + contMgmContext_p context = NULL; + + if ( selcnt <= 0 ) + return; + if ( (!NoticeMessage2( 1, _("Are you sure you want to delete the %d control element(s)"), _("Yes"), _("No"), selcnt ) ) ) + return; + cnt = wListGetCount( (wList_p)controlPLs[0].control ); + UndoStart( _("Control Elements"), "delete" ); + for ( inx=0; inx<cnt; inx++ ) { + if ( !wListGetItemSelected( (wList_p)controlPLs[0].control, inx ) ) + continue; + context = (contMgmContext_p)wListGetItemContext( controlSelL, inx ); + context->proc( CONTMGM_DO_DELETE, context->data ); + MyFree( context ); + wListDelete( controlSelL, inx ); + inx--; + cnt--; + } + UndoEnd(); + DoChangeNotification( CHANGE_PARAMS ); +} + +static void ControlDone( void * action ) +{ + contMgmContext_p context = NULL; + wIndex_t linx, lcnt; + + if (AnyHILIGHT) { + lcnt = wListGetCount( (wList_p)controlPLs[0].control ); + for (linx=0; + linx < lcnt; + linx++ ) { + context = (contMgmContext_p)wListGetItemContext( controlSelL, linx ); + context->proc( CONTMGM_UN_HILIGHT, context->data ); + } + } + wHide( controlPG.win ); +} + + +EXPORT void ContMgmLoad( + wIcon_p icon, + contMgmCallBack_p proc, + void * data ) +{ + contMgmContext_p context; + context = MyMalloc( sizeof *context ); + context->proc = proc; + context->data = data; + context->icon = icon; + context->proc( CONTMGM_GET_TITLE, context->data ); + wListAddValue( controlSelL, message, icon, context ); +} + + +static void LoadControlMgmList( void ) +{ + wIndex_t curInx, cnt=0; + long tempL; + contMgmContext_p context; + contMgmContext_t curContext; + + curInx = wListGetIndex( controlSelL ); + curContext.proc = NULL; + curContext.data = NULL; + curContext.icon = NULL; + if ( curInx >= 0 ) { + context = (contMgmContext_p)wListGetItemContext( controlSelL, curInx ); + if ( context != NULL ) + curContext = *context; + } + cnt = wListGetCount( controlSelL ); + for ( curInx=0; curInx<cnt; curInx++ ) { + context = (contMgmContext_p)wListGetItemContext( controlSelL, curInx ); + if ( context ) + MyFree( context ); + } + curInx = wListGetIndex( controlSelL ); + wControlShow( (wControl_p)controlSelL, FALSE ); + wListClear( controlSelL ); + + BlockMgmLoad(); + SwitchmotorMgmLoad(); + SignalMgmLoad(); + ControlMgmLoad(); + SensorMgmLoad(); + +#ifdef LATER + curInx = 0; + cnt = wListGetCount( controlSelL ); + if ( curContext.proc != NULL ) { + for ( curInx=0; curInx<cnt; curInx++ ) { + context = (contMgmContext_p)wListGetItemContext( controlSelL, curInx ); + if ( context && + context->proc == curContext.proc && + context->data == curContext.data ) + break; + } + } + if ( curInx >= cnt ) + curInx = (cnt>0?0:-1); + + wListSetIndex( controlSelL, curInx ); + tempL = curInx; +#endif + tempL = -1; + ControlDlgUpdate( &controlPG, I_CONTROLLIST, &tempL ); + wControlShow( (wControl_p)controlSelL, TRUE ); +} + + +static void ContMgmChange( long changes ) +{ + if (changes) { + if (changed) { + changed = 1; + checkPtMark = 1; + } + } + if ((changes&CHANGE_PARAMS) == 0 || + controlPG.win == NULL || !wWinIsVisible(controlPG.win) ) + return; + + LoadControlMgmList(); +} + + + +static void DoControlMgr( void * junk ) +{ + if (controlPG.win == NULL) { + ParamCreateDialog( &controlPG, MakeWindowTitle(_("Manage Layout Control Elements")), _("Done"), ControlDone, NULL, TRUE, NULL, F_RESIZE|F_RECALLSIZE|F_BLOCK, ControlDlgUpdate ); + } else { + wListClear( controlSelL ); + } + /*ParamLoadControls( &controlPG );*/ + /*ParamGroupRecord( &controlPG );*/ + LoadControlMgmList(); + wShow( controlPG.win ); +} + + +EXPORT addButtonCallBack_t ControlMgrInit( void ) +{ + ParamRegister( &controlPG ); + /*ParamRegister( &contMgmContentsPG );*/ + RegisterChangeNotification( ContMgmChange ); + return &DoControlMgr; +} diff --git a/app/bin/dprmfile.c b/app/bin/dprmfile.c index 18b0cbe..e9cfc80 100644 --- a/app/bin/dprmfile.c +++ b/app/bin/dprmfile.c @@ -26,7 +26,7 @@ #include <stdint.h> -#define PARAM_SUBDIR ("\\params") +#define PARAM_SUBDIR FILE_SEP_CHAR "params" /**************************************************************************** * diff --git a/app/bin/draw.c b/app/bin/draw.c index c04373c..92814e0 100644 --- a/app/bin/draw.c +++ b/app/bin/draw.c @@ -1154,7 +1154,7 @@ EXPORT void GetRoomSize( coOrd * froomSize ) } -static void MapRedraw( void ) +EXPORT void MapRedraw( void ) { if (inPlaybackQuit) return; diff --git a/app/bin/draw.h b/app/bin/draw.h index aedc2b6..db8d91a 100644 --- a/app/bin/draw.h +++ b/app/bin/draw.h @@ -174,6 +174,7 @@ void GetRoomSize( coOrd * ); void DoRedraw( void ); void SetMainSize( void ); void MainRedraw( void ); +void MapRedraw( void ); void DrawMarkers( void ); void DrawMapBoundingBox( BOOL_T ); void DrawTicks( drawCmd_p, coOrd ); diff --git a/app/bin/dxfformat.c b/app/bin/dxfformat.c new file mode 100644 index 0000000..4e1c775 --- /dev/null +++ b/app/bin/dxfformat.c @@ -0,0 +1,368 @@ +/** \file dxfformat.c +* Formating of DXF commands and parameters +*/ + +/* XTrkCad - Model Railroad CAD +* Copyright (C)2017 Martin Fischer +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* 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. +*/ +#include <stdarg.h> +#include <string.h> +#include <stdio.h> +#ifdef HAVE_MALLOC_H +#include <malloc.h> +#endif + +#include <dynstring.h> +#include "dxfformat.h" + +extern char *sProdNameUpper; +extern long units; /**< meaning is 0 = English, 1 = metric */ + +static char *dxfDimensionDefaults[][3] = { /**< default values for dimensions, English, metric and DXF variable name */ + { "1.0", "25.0", "$DIMTXT" }, + { "0.8", "20.0", "$DIMASZ"} +}; + +/** +* Build and format layer name. The name is created by appending the layer number +* to the basic layer name. +* +* \param result OUT buffer for result +* \param name IN base part of name +* \param layer IN layer number +*/ + +void DxfLayerName(DynString *result, char *name, int layer) +{ + DynStringPrintf(result, DXF_INDENT "8\n%s%d\n", name, layer); +} + +/** +* Build and format a position. If it specifies a point the value +* is assumed to be in inches and will be converted to millimeters +* if the metric system is active. +* If it is an angle (group codes 50 to 59) it is not converted. +* +* \param result OUT buffer for result +* \param type IN type of position following DXF specs +* \param value IN position +*/ + +void DxfFormatPosition(DynString *result, int type, double value) +{ + if (units == 1) + { + if( type < 50 || type > 58 ) + value *= 25.4; + } + + DynStringPrintf(result, DXF_INDENT "%d\n%0.6f\n", type, value); +} + +/** +* Build and format the line style definition +* +* \param result OUT buffer for result +* \param type IN line style TRUE for dashed, FALSE for solid lines +*/ + +void DxfLineStyle(DynString *result, int isDashed) +{ + DynStringPrintf(result, DXF_INDENT "6\n%s\n", + (isDashed ? "DASHED" : "CONTINUOUS")); +} + +/** +* Build and format layer name. The name is created by appending the layer number +* to the basic layer name. The result is appended to the existing result buffer. +* +* \param output OUT buffer for result +* \param basename IN base part of name +* \param layer IN layer number +*/ + +static void +DxfAppendLayerName(DynString *output, int layer) +{ + DynString formatted = NaS; + DynStringMalloc(&formatted, 0); + DxfLayerName(&formatted, sProdNameUpper, layer); + DynStringCatStr(output, &formatted); + DynStringFree(&formatted); +} + +/** +* Build and format a position. The result is appended to the existing result buffer. +* +* \param output OUT buffer for result +* \param type IN type of position following DXF specs +* \param value IN position +*/ + +static void +DxfAppendPosition(DynString *output, int type, double value) +{ + DynString formatted = NaS; + DynStringMalloc(&formatted, 0); + DxfFormatPosition(&formatted, type, value); + DynStringCatStr(output, &formatted); + DynStringFree(&formatted); +} + +/** +* Build and format the line style definition. The result is appended to the existing result buffer. +* +* \param result OUT buffer for result +* \param type IN line style TRUE for dashed, FALSE for solid lines +*/ + +static void +DxfAppendLineStyle(DynString *output, int style) +{ + DynString formatted = NaS; + DynStringMalloc(&formatted, 0); + DxfLineStyle(&formatted, style); + DynStringCatStr(output, &formatted); + DynStringFree(&formatted); +} + +/** +* Format a complete LINE command after DXF spec +* +* \param result OUT buffer for the completed command +* \param layer IN number part of the layer +* \param x0, y0 IN first endpoint +* \param x1, y1 IN second endpoint +* \param style IN line style, TRUE for dashed, FALSE for continuous +*/ + +void +DxfLineCommand(DynString *result, int layer, double x0, + double y0, double x1, double y1, int style) +{ + DynStringCatCStr(result, DXF_INDENT "0\nLINE\n"); + DxfAppendLayerName(result, layer); + DxfAppendPosition(result, 10, x0); + DxfAppendPosition(result, 20, y0); + DxfAppendPosition(result, 11, x1); + DxfAppendPosition(result, 21, y1); + DxfAppendLineStyle(result, style); +} + +/** +* Format a complete CIRCLE command after DXF spec +* +* \param result OUT buffer for the completed command +* \param layer IN number part of the layer +* \param x, y IN center point +* \param r IN radius +* \param style IN line style, TRUE for dashed, FALSE for continuous +*/ + +void +DxfCircleCommand(DynString *result, int layer, double x, + double y, double r, int style) +{ + DynStringCatCStr(result, DXF_INDENT "0\nCIRCLE\n"); + DxfAppendPosition(result, 10, x); + DxfAppendPosition(result, 20, y); + DxfAppendPosition(result, 40, r); + DxfAppendLayerName(result, layer); + DxfAppendLineStyle(result, style); +} + +/** +* Format a complete ARC command after DXF spec +* +* \param result OUT buffer for the completed command +* \param layer IN number part of the layer +* \param x, y IN center point +* \param r IN radius +* \param a0 IN starting angle +* \param a1 IN ending angle +* \param style IN line style, TRUE for dashed, FALSE for continuous +*/ + +void +DxfArcCommand(DynString *result, int layer, double x, double y, + double r, double a0, double a1, int style) +{ + DynStringCatCStr(result, DXF_INDENT "0\nARC\n"); + DxfAppendPosition(result, 10, x); + DxfAppendPosition(result, 20, y); + DxfAppendPosition(result, 40, r); + DxfAppendPosition(result, 50, a0); + DxfAppendPosition(result, 51, a0+a1); + DxfAppendLayerName(result, layer); + DxfAppendLineStyle(result, style); +} + +/** +* Format a complete TEXT command after DXF spec +* +* \param result OUT buffer for the completed command +* \param layer IN number part of the layer +* \param x, y IN text position +* \param size IN font size +* \param text IN text +*/ + +void +DxfTextCommand(DynString *result, int layer, double x, + double y, double size, char *text) +{ + DynStringCatCStr(result, DXF_INDENT "0\nTEXT\n"); + DynStringCatCStrs(result, DXF_INDENT "1\n", text, "\n", NULL); + DxfAppendPosition(result, 10, x); + DxfAppendPosition(result, 20, y); + DxfAppendPosition(result, 40, size/72.0); + DxfAppendLayerName(result, layer); +} + +/** + * Append the header lines needed to define the measurement system. This includes the + * definition of the measurement system (metric or English) vie the $MEASUREMENT variable + * and the units i.e. inches for English and mm for metric. + * + * \PARAM result OUT buffer for the completed command + */ + +void +DxfUnits(DynString *result) +{ + char *value; + DynStringCatCStr(result, DXF_INDENT "9\n$MEASUREMENT\n 70\n"); + + if (units == 1) { + value = "1\n"; + } else { + value = "0\n"; + } + + DynStringCatCStr(result, value); + DynStringCatCStr(result, DXF_INDENT "9\n$INSUNITS\n 70\n"); + + if (units == 1) { + value = "4\n"; + } else { + value = "1\n"; + } + + DynStringCatCStr(result, value); +} + +/** +* Define a size of dimensions. The default values are taken from +* static array dxfDimensionDefaults +* +* \PARAM result OUT the completed command is appended to this buffer +* \PARAM dimension IN dimension variable to set +*/ + +void +DxfDimensionSize(DynString *result, enum DXF_DIMENSIONS dimension ) +{ + DynString formatted; + DynStringMalloc(&formatted, 0); + + DynStringPrintf(&formatted, + DXF_INDENT "9\n%s\n 40\n%s\n", + dxfDimensionDefaults[dimension][2], + dxfDimensionDefaults[dimension][units]); + + DynStringCatStr(result, &formatted); + DynStringFree(&formatted); +} + +/** +* Create the complete prologue for a DXF file. Includes the header section, +* a table for line styles and a table for layers. +* +* \param result OUT buffer for the completed command +* \param layerCount IN count of defined layers +* \param x0, y0 IN minimum (left bottom) position +* \param x1, y1 IN maximum (top right) position +*/ + +void +DxfPrologue(DynString *result, int layerCount, double x0, double y0, double x1, + double y1) +{ + int i; + DynString layer = NaS; + DynStringMalloc(&layer, 0); + DynStringCatCStr(result, "\ + 0\nSECTION\n\ + 2\nHEADER\n\ + 9\n$ACADVER\n 1\nAC1015\n"); + DxfUnits(result); + DxfDimensionSize(result, DXF_DIMTEXTSIZE); + DxfDimensionSize(result, DXF_DIMARROWSIZE); + + DynStringCatCStr(result, " 9\n$EXTMIN\n"); + DxfAppendPosition(result, 10, x0); + DxfAppendPosition(result, 20, y0); + DynStringCatCStr(result, " 9\n$EXTMAX\n"); + DxfAppendPosition(result, 10, x1); + DxfAppendPosition(result, 20, y1); + DynStringCatCStr(result, "\ + 9\n$TEXTSTYLE\n 7\nSTANDARD\n\ + 0\nENDSEC\n\ + 0\nSECTION\n\ + 2\nTABLES\n\ + 0\nTABLE\n\ + 2\nLTYPE\n\ + 0\nLTYPE\n 2\nCONTINUOUS\n 70\n0\n\ + 3\nSolid line\n\ + 72\n65\n 73\n0\n 40\n0\n\ + 0\nLTYPE\n 2\nDASHED\n 70\n0\n\ + 3\n__ __ __ __ __ __ __ __ __ __ __ __ __ __ __\n\ + 72\n65\n 73\n2\n 40\n0.15\n 49\n0.1\n 49\n-0.05\n\ + 0\nLTYPE\n 2\nDOT\n 70\n0\n\ + 3\n...............................................\n\ + 72\n65\n 73\n2\n 40\n0.1\n 49\n0\n 49\n-0.05\n\ + 0\nENDTAB\n\ + 0\nTABLE\n\ + 2\nLAYER\n\ + 70\n0\n"); + + for (i = 0; i < layerCount; i++) { + DynStringPrintf(&layer, + DXF_INDENT"0\nLAYER\n 2\n%s%d\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n", + sProdNameUpper, i + 1); + DynStringCatStr(result, &layer); + } + + DynStringCatCStr(result, "\ + 0\nENDTAB\n\ + 0\nENDSEC\n\ + 0\nSECTION\n\ + 2\nENTITIES\n"); +} + +/** +* Create the file footer for a DXF file. Closes the open section and places +* an end-of-file marker +* +* \param result OUT buffer for the completed command +*/ + +void +DxfEpilogue(DynString *result) +{ + DynStringCatCStr(result, DXF_INDENT "0\nENDSEC\n" DXF_INDENT "0\nEOF\n"); +} diff --git a/app/bin/dxfformat.h b/app/bin/dxfformat.h new file mode 100644 index 0000000..88db568 --- /dev/null +++ b/app/bin/dxfformat.h @@ -0,0 +1,26 @@ +#ifndef HAVE_DXFFORMAT_H +#define HAVE_DXFFORMAT_H + +enum DXF_DIMENSIONS +{ + DXF_DIMTEXTSIZE, + DXF_DIMARROWSIZE +}; + +void DxfLayerName(DynString *result, char *name, int layer); +void DxfFormatPosition(DynString *result, int type, double value); +void DxfLineStyle(DynString *result, int isDashed); + +void DxfLineCommand(DynString *result, int layer, double x0, double yo, double x1, double y1, int style); +void DxfCircleCommand(DynString *result, int layer, double x, double y, double r, int style); +void DxfArcCommand(DynString *result, int layer, double x, double y, double r, double a0, double a1, int style); +void DxfTextCommand(DynString *result, int layer, double x, double y, double size, char *text); +void DxfUnits(DynString *result); +void DxfDimensionSize(DynString *result, enum DXF_DIMENSIONS dimension); + +void DxfPrologue(DynString *result, int layerCount, double x0, double y0, double x1, double y1); +void DxfEpilogue(DynString *result); +#define DXF_INDENT " " + +#endif // !HAVE_DXFFORMAT_H + diff --git a/app/bin/dxfoutput.c b/app/bin/dxfoutput.c new file mode 100644 index 0000000..91a822f --- /dev/null +++ b/app/bin/dxfoutput.c @@ -0,0 +1,230 @@ +/** \file dxfoutput.c + * Exporting DXF files +*/ + +/* XTrkCad - Model Railroad CAD + * Copyright (C) 2005 Dave Bullis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + */ + +#include <stdio.h> +#include <string.h> +#include <time.h> +#ifdef WINDOWS + #include <io.h> + #include <windows.h> + #if _MSC_VER >=1400 + #define strdup _strdup + #endif +#else + #include <errno.h> +#endif + +#include <xtrkcad-config.h> +#include <locale.h> +#include <assert.h> +#include "track.h" +#include "i18n.h" +#include <dynstring.h> + +#include "dxfformat.h" + +static struct wFilSel_t * exportDXFFile_fs; + +static void DxfLine( + drawCmd_p d, + coOrd p0, + coOrd p1, + wDrawWidth width, + wDrawColor color) +{ + DynString command = NaS; + DynStringMalloc(&command, 100); + DxfLineCommand(&command, + curTrackLayer + 1, + p0.x, p0.y, + p1.x, p1.y, + ((d->options&DC_DASH) != 0)); + fputs(DynStringToCStr(&command), (FILE *)d->d); + DynStringFree(&command); +} + +static void DxfArc( + drawCmd_p d, + coOrd p, + DIST_T r, + ANGLE_T angle0, + ANGLE_T angle1, + BOOL_T drawCenter, + wDrawWidth width, + wDrawColor color) +{ + DynString command = NaS; + DynStringMalloc(&command, 100); + angle0 = NormalizeAngle(90.0-(angle0+angle1)); + + if (angle1 >= 360.0) { + DxfCircleCommand(&command, + curTrackLayer + 1, + p.x, + p.y, + r, + ((d->options&DC_DASH) != 0)); + } else { + DxfArcCommand(&command, + curTrackLayer + 1, + p.x, + p.y, + r, + angle0, + angle1, + ((d->options&DC_DASH) != 0)); + } + + fputs(DynStringToCStr(&command), (FILE *)d->d); + DynStringFree(&command); +} + +static void DxfString( + drawCmd_p d, + coOrd p, + ANGLE_T a, + char * s, + wFont_p fp, + FONTSIZE_T fontSize, + wDrawColor color) +{ + DynString command = NaS; + DynStringMalloc(&command, 100); + DxfTextCommand(&command, + curTrackLayer + 1, + p.x, + p.y, + fontSize, + s); + fputs(DynStringToCStr(&command), (FILE *)d->d); + DynStringFree(&command); +} + +static void DxfBitMap( + drawCmd_p d, + coOrd p, + wDrawBitMap_p bm, + wDrawColor color) +{ +} + +static void DxfFillPoly( + drawCmd_p d, + int cnt, + coOrd * pts, + wDrawColor color) +{ + int inx; + + for (inx=1; inx<cnt; inx++) { + DxfLine(d, pts[inx-1], pts[inx], 0, color); + } + + DxfLine(d, pts[cnt-1], pts[0], 0, color); +} + +static void DxfFillCircle(drawCmd_p d, coOrd center, DIST_T radius, + wDrawColor color) +{ + DxfArc(d, center, radius, 0.0, 360, FALSE, 0, color); +} + + +static drawFuncs_t dxfDrawFuncs = { + 0, + DxfLine, + DxfArc, + DxfString, + DxfBitMap, + DxfFillPoly, + DxfFillCircle +}; + +static drawCmd_t dxfD = { + NULL, &dxfDrawFuncs, 0, 1.0, 0.0, {0.0,0.0}, {0.0,0.0}, Pix2CoOrd, CoOrd2Pix, 100.0 +}; + +static int DoExportDXFTracks( + int cnt, + char ** fileName, + void * data) +{ + time_t clock; + char *oldLocale; + DynString command = NaS; + FILE * dxfF; + + assert(fileName != NULL); + assert(cnt == 1); + + DynStringMalloc(&command, 100); + + SetCurrentPath(DXFPATHKEY, fileName[ 0 ]); + dxfF = fopen(fileName[0], "w"); + + if (dxfF==NULL) { + NoticeMessage(MSG_OPEN_FAIL, _("Continue"), NULL, "DXF", fileName[0], + strerror(errno)); + return FALSE; + } + + oldLocale = SaveLocale("C"); + wSetCursor(wCursorWait); + time(&clock); + + DxfPrologue(&command, 10, 0.0, 0.0, mapD.size.x, mapD.size.y); + fputs(DynStringToCStr(&command), dxfF); + dxfD.d = (wDraw_p)dxfF; + + DrawSelectedTracks(&dxfD); + + DynStringClear(&command); + DxfEpilogue(&command); + fputs(DynStringToCStr(&command), dxfF); + + fclose(dxfF); + RestoreLocale(oldLocale); + Reset(); + wSetCursor(wCursorNormal); + return TRUE; +} + +/** +* Create and show the dialog for selected the DXF export filename +*/ + +void DoExportDXF(void) +{ + //if (selectedTrackCount <= 0) { + // ErrorMessage(MSG_NO_SELECTED_TRK); + // return; + //} + assert(selectedTrackCount > 0); + + if (exportDXFFile_fs == NULL) + exportDXFFile_fs = wFilSelCreate(mainW, FS_SAVE, 0, _("Export to DXF"), + sDXFFilePattern, DoExportDXFTracks, NULL); + + wFilSelect(exportDXFFile_fs, curDirName); +} + + diff --git a/app/bin/fileio.c b/app/bin/fileio.c index 23216b8..da0de68 100644 --- a/app/bin/fileio.c +++ b/app/bin/fileio.c @@ -1,6 +1,6 @@ /** \file fileio.c - * Loading and saving files. Handles trackplans as well as DXF export. - */ + * Loading and saving files. Handles trackplans, XTrackCAD exports and cut/paste +*/ /* XTrkCad - Model Railroad CAD * Copyright (C) 2005 Dave Bullis @@ -1039,7 +1039,7 @@ static int SaveTracks( wMenuListAdd( fileList_ml, 0, nameOfFile, MyStrdup(fileName[ 0 ]) ); checkPtMark = changed = 0; - if (curPathName != fileName[ 0 ]) + if (strcmp(curPathName, fileName[ 0 ])) strcpy( curPathName, fileName[ 0 ] ); curFileName = FindName( curPathName ); @@ -1053,13 +1053,14 @@ static int SaveTracks( EXPORT void DoSave( doSaveCallBack_p after ) { doAfterSave = after; - if (curPathName[0] == 0) { + if (curPathName[0] == '\0') { if (saveFile_fs == NULL) saveFile_fs = wFilSelCreate( mainW, FS_SAVE, 0, _("Save Tracks"), sSourceFilePattern, SaveTracks, NULL ); wFilSelect( saveFile_fs, curDirName ); } else { - SaveTracks( 1, &curFileName, NULL ); + char *temp = curPathName; + SaveTracks( 1, &temp, NULL ); } SetWindowTitle(); } @@ -1224,7 +1225,6 @@ EXPORT int LoadCheckpoint( void ) static struct wFilSel_t * exportFile_fs; static struct wFilSel_t * importFile_fs; -static struct wFilSel_t * exportDXFFile_fs; static int ImportTracks( @@ -1330,187 +1330,6 @@ EXPORT void DoExport( void ) } -static FILE * dxfF; -static void DxfLine( - drawCmd_p d, - coOrd p0, - coOrd p1, - wDrawWidth width, - wDrawColor color ) -{ - fprintf(dxfF, " 0\nLINE\n" ); - fprintf(dxfF, " 8\n%s%d\n", sProdNameUpper, curTrackLayer+1 ); - fprintf(dxfF, " 10\n%0.6f\n 20\n%0.6f\n 11\n%0.6f\n 21\n%0.6f\n", - p0.x, p0.y, p1.x, p1.y ); - fprintf(dxfF, " 6\n%s\n", (d->options&DC_DASH)?"DASHED":"CONTINUOUS" ); -} - -static void DxfArc( - drawCmd_p d, - coOrd p, - DIST_T r, - ANGLE_T angle0, - ANGLE_T angle1, - BOOL_T drawCenter, - wDrawWidth width, - wDrawColor color ) -{ - angle0 = NormalizeAngle(90.0-(angle0+angle1)); - if (angle1 >= 360.0) { - fprintf(dxfF, " 0\nCIRCLE\n" ); - fprintf(dxfF, " 10\n%0.6f\n 20\n%0.6f\n 40\n%0.6f\n", - p.x, p.y, r ); - } else { - fprintf(dxfF, " 0\nARC\n" ); - fprintf(dxfF, " 10\n%0.6f\n 20\n%0.6f\n 40\n%0.6f\n 50\n%0.6f\n 51\n%0.6f\n", - p.x, p.y, r, angle0, angle0+angle1 ); - } - fprintf(dxfF, " 8\n%s%d\n", sProdNameUpper, curTrackLayer+1 ); - fprintf(dxfF, " 6\n%s\n", (d->options&DC_DASH)?"DASHED":"CONTINUOUS" ); -} - -static void DxfString( - drawCmd_p d, - coOrd p, - ANGLE_T a, - char * s, - wFont_p fp, - FONTSIZE_T fontSize, - wDrawColor color ) -{ - fprintf(dxfF, " 0\nTEXT\n" ); - fprintf(dxfF, " 1\n%s\n", s ); - fprintf(dxfF, " 8\n%s%d\n", sProdNameUpper, curTrackLayer+1 ); - fprintf(dxfF, " 10\n%0.6f\n 20\n%0.6f\n", p.x, p.y ); - fprintf(dxfF, " 40\n%0.6f\n", fontSize/72.0 ); -} - -static void DxfBitMap( - drawCmd_p d, - coOrd p, - wDrawBitMap_p bm, - wDrawColor color ) -{ -} - -static void DxfFillPoly( - drawCmd_p d, - int cnt, - coOrd * pts, - wDrawColor color ) -{ - int inx; - for (inx=1; inx<cnt; inx++) { - DxfLine( d, pts[inx-1], pts[inx], 0, color ); - } - DxfLine( d, pts[cnt-1], pts[0], 0, color ); -} - -static void DxfFillCircle( drawCmd_p d, coOrd center, DIST_T radius, wDrawColor color ) -{ - DxfArc( d, center, radius, 0.0, 360, FALSE, 0, color ); -} - - -static drawFuncs_t dxfDrawFuncs = { - 0, - DxfLine, - DxfArc, - DxfString, - DxfBitMap, - DxfFillPoly, - DxfFillCircle }; - -static drawCmd_t dxfD = { - NULL, &dxfDrawFuncs, 0, 1.0, 0.0, {0.0,0.0}, {0.0,0.0}, Pix2CoOrd, CoOrd2Pix, 100.0 }; - -static int DoExportDXFTracks( - int cnt, - char ** fileName, - void * data ) -{ - time_t clock; - char *oldLocale; - - assert( fileName != NULL ); - assert( cnt == 1 ); - - SetCurrentPath( DXFPATHKEY, fileName[ 0 ] ); - dxfF = fopen( fileName[0], "w" ); - if (dxfF==NULL) { - NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, "DXF", fileName[0], strerror(errno) ); - return FALSE; - } - - oldLocale = SaveLocale( "C" ); - wSetCursor( wCursorWait ); - time(&clock); - fprintf(dxfF,"\ - 0\nSECTION\n\ - 2\nHEADER\n\ - 9\n$ACADVER\n 1\nAC1009\n\ - 9\n$EXTMIN\n 10\n%0.6f\n 20\n%0.6f\n\ - 9\n$EXTMAX\n 10\n%0.6f\n 20\n%0.6f\n\ - 9\n$TEXTSTYLE\n 7\nSTANDARD\n\ - 0\nENDSEC\n\ - 0\nSECTION\n\ - 2\nTABLES\n\ - 0\nTABLE\n\ - 2\nLTYPE\n\ - 0\nLTYPE\n 2\nCONTINUOUS\n 70\n0\n\ - 3\nSolid line\n\ - 72\n65\n 73\n0\n 40\n0\n\ - 0\nLTYPE\n 2\nDASHED\n 70\n0\n\ - 3\n__ __ __ __ __ __ __ __ __ __ __ __ __ __ __\n\ - 72\n65\n 73\n2\n 40\n0.15\n 49\n0.1\n 49\n-0.05\n\ - 0\nLTYPE\n 2\nDOT\n 70\n0\n\ - 3\n...............................................\n\ - 72\n65\n 73\n2\n 40\n0.1\n 49\n0\n 49\n-0.05\n\ - 0\nENDTAB\n\ - 0\nTABLE\n\ - 2\nLAYER\n\ - 70\n0\n\ - 0\nLAYER\n 2\n%s1\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\ - 0\nLAYER\n 2\n%s2\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\ - 0\nLAYER\n 2\n%s3\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\ - 0\nLAYER\n 2\n%s4\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\ - 0\nLAYER\n 2\n%s5\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\ - 0\nLAYER\n 2\n%s6\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\ - 0\nLAYER\n 2\n%s7\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\ - 0\nLAYER\n 2\n%s8\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\ - 0\nLAYER\n 2\n%s9\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\ - 0\nLAYER\n 2\n%s10\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\ - 0\nENDTAB\n\ - 0\nENDSEC\n\ - 0\nSECTION\n\ - 2\nENTITIES\n\ -", - 0.0, 0.0, mapD.size.x, mapD.size.y, - sProdNameUpper, sProdNameUpper, sProdNameUpper, sProdNameUpper, sProdNameUpper, - sProdNameUpper, sProdNameUpper, sProdNameUpper, sProdNameUpper, sProdNameUpper ); - DrawSelectedTracks( &dxfD ); - fprintf(dxfF," 0\nENDSEC\n"); - fprintf(dxfF," 0\nEOF\n"); - fclose(dxfF); - RestoreLocale( oldLocale ); - Reset(); - wSetCursor( wCursorNormal ); - return TRUE; -} - - -void DoExportDXF( void ) -{ - if (selectedTrackCount <= 0) { - ErrorMessage( MSG_NO_SELECTED_TRK ); - return; - } - if (exportDXFFile_fs == NULL) - exportDXFFile_fs = wFilSelCreate( mainW, FS_SAVE, 0, _("Export to DXF"), - sDXFFilePattern, DoExportDXFTracks, NULL ); - - wFilSelect( exportDXFFile_fs, curDirName ); -} EXPORT BOOL_T EditCopy( void ) { diff --git a/app/bin/helphelper.c b/app/bin/helphelper.c new file mode 100644 index 0000000..013ff0a --- /dev/null +++ b/app/bin/helphelper.c @@ -0,0 +1,146 @@ +/** \file helphelper.c + * use OSX Help system + */ + +/* XTrkCad - Model Railroad CAD + * Copyright (C) 2015 Martin Fischer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + */ + +#import <CoreFoundation/CoreFoundation.h> +#import <Carbon/Carbon.h> + +#include <stdio.h> +#include <stdlib.h> +#include <dirent.h> +#include <sys/time.h> +#include <signal.h> +#include <unistd.h> +#include <string.h> +#include <ctype.h> +#include <assert.h> +#include <errno.h> +#include <fcntl.h> + +#include <stdint.h> + +#define HELPCOMMANDPIPE "/tmp/helppipe" +#define EXITCOMMAND "##exit##" + + +OSStatus MyGoToHelpPage (CFStringRef pagePath, CFStringRef anchorName) +{ + CFBundleRef myApplicationBundle = NULL; + CFStringRef myBookName = NULL; + OSStatus err = noErr; + printf("HelpHelper: Started to look for help\n"); + + myApplicationBundle = CFBundleGetMainBundle(); + if (myApplicationBundle == NULL) { + printf("HelpHelper: Error - No Application Bundle\n"); + err = fnfErr; + return err; + } + printf("HelpHelper: Application Bundle Found\n"); + + myBookName = CFBundleGetValueForInfoDictionaryKey( + myApplicationBundle, + CFSTR("CFBundleHelpBookName")); + if (myBookName == NULL) { + myBookName = CFStringCreateWithCString(NULL, "XTrackCAD Help", kCFStringEncodingMacRoman); + printf("HelpHelper: Defaulting to 'XTrackCAD Help'\n" ); + err = fnfErr; + return err; + } + printf("HelpHelper: BookName dictionary name %s found\n",CFStringGetCStringPtr(myBookName, kCFStringEncodingMacRoman)); + + if (CFGetTypeID(myBookName) != CFStringGetTypeID()) { + printf("HelpHelper: Error - BookName is not a string\n" ); + err = paramErr; + } + + if (err == noErr) { + err = AHGotoPage (myBookName, pagePath, anchorName); + if (err != noErr) { + printf("HelpHelper: Error in AHGoToPage('%s','%s')\n",CFStringGetCStringPtr(myBookName, kCFStringEncodingMacRoman), CFStringGetCStringPtr(pagePath, kCFStringEncodingMacRoman)); + } + } + + return err; + +}; + +int displayHelp(char* name) { + CFStringRef str = CFStringCreateWithCString(NULL,name,kCFStringEncodingMacRoman); + OSStatus err = MyGoToHelpPage(str, NULL); + if (err != noErr) printf("HelpHelper: MyGoToHelpPage had error %d\n", err); + return err; + +}; + +int +main( int argc, char **argv ) +{ + int handleOfPipe = 0; + char buffer[ 100 ]; + char issue[ 100 ]; + + int len; + int finished = 0; + int numBytes = 0; + int numBytes2 = 0; + + printf( "HelpHelper: starting!\n" ); + + handleOfPipe = open( HELPCOMMANDPIPE, O_RDONLY ); + if( handleOfPipe ) { + printf( "HelpHelper: opened pipe for reading\n" ); + while( !finished ) { + printf( "HelpHelper: reading from pipe...\n" ); + numBytes = read( handleOfPipe, &len, sizeof( int )); + + if( numBytes > 0 ) + printf( "HelpHelper: read %d bytes\n", numBytes ); + if( numBytes == sizeof(int)) { + printf( "HelpHelper: Expecting %d bytes\n", len ); + numBytes2 = read( handleOfPipe, buffer, len + 1 ); + if (numBytes2 > 0) + printf( "HelpHelper: Display help on: %s\n", buffer ); + + if( !strcmp(buffer, EXITCOMMAND )) { + finished = 1; + } else { + if (displayHelp(buffer) != 0) + printf( "HelpHelper: Error\n"); + } + } + if( numBytes <= 0 ) { + printf( "HelpHelper: exiting on pipe error\n" ); + exit( 1 ); + } + } + } else { + printf( "HelpHelper: Could not open pipe for reading\n" ); + } + + printf( "HelpHelper: exiting!" ); + + exit( 0 ); +}; + + + + diff --git a/app/bin/misc.c b/app/bin/misc.c index 77b46a2..b506f98 100644 --- a/app/bin/misc.c +++ b/app/bin/misc.c @@ -713,8 +713,8 @@ EXPORT void SelectFont( void ) * */ -#define COMMAND_MAX (160) -#define BUTTON_MAX (160) +#define COMMAND_MAX (170) +#define BUTTON_MAX (170) #define NUM_CMDMENUS (4) #ifdef LATER @@ -2210,8 +2210,11 @@ static void CreateMenus( void ) cmdGroup = BG_CONTROL; InitCmdBlock( addM ); - InitCmdSwitchMotor( addM ); - + InitCmdSwitchMotor( addM ); + InitCmdSignal( addM ); + InitCmdControl( addM ); + InitCmdSensor( addM ); + /* * CHANGE MENU */ @@ -2321,7 +2324,8 @@ static void CreateMenus( void ) InitNewTurn( wMenuMenuCreate( manageM, "cmdTurnoutNew", _("Tur&nout Designer...") ) ); - MiscMenuItemCreate( manageM, NULL, "cmdGroup", _("&Group"), ACCL_GROUP, (void*)(wMenuCallBack_p)DoGroup, IC_SELECTED, (void *)0 ); + MiscMenuItemCreate( manageM, NULL, "smdContmgm", _("Layout &Control Elements"), ACCL_CONTMGM,(void*)ControlMgrInit(),0,(void*) 0); + MiscMenuItemCreate( manageM, NULL, "cmdGroup", _("&Group"), ACCL_GROUP, (void*)(wMenuCallBack_p)DoGroup, IC_SELECTED, (void *)0 ); MiscMenuItemCreate( manageM, NULL, "cmdUngroup", _("&Ungroup"), ACCL_UNGROUP, (void*)(wMenuCallBack_p)DoUngroup, IC_SELECTED, (void *)0 ); MiscMenuItemCreate( manageM, NULL, "cmdCustmgm", _("Custom defined parts..."), ACCL_CUSTMGM, (void*)CustomMgrInit(), 0, (void *)0 ); diff --git a/app/bin/misc.h b/app/bin/misc.h index 7d3231e..1747189 100644 --- a/app/bin/misc.h +++ b/app/bin/misc.h @@ -318,6 +318,7 @@ addButtonCallBack_t OutputBitMapInit( void ); addButtonCallBack_t CustomMgrInit( void ); addButtonCallBack_t PriceListInit( void ); addButtonCallBack_t ParamFilesInit( void ); +addButtonCallBack_t ControlMgrInit ( void ); wIndex_t InitGrid( wMenu_p menu ); @@ -373,6 +374,18 @@ void CarCustMgmLoad(); BOOL_T CompoundCustomSave(FILE*); BOOL_T CarCustomSave(FILE*); +/* dcontmgm.c */ +#define CONTMGM_CAN_EDIT (1) +#define CONTMGM_DO_EDIT (2) +#define CONTMGM_CAN_DELETE (3) +#define CONTMGM_DO_DELETE (4) +#define CONTMGM_GET_TITLE (5) +#define CONTMGM_DO_HILIGHT (6) +#define CONTMGM_UN_HILIGHT (7) + +typedef int (*contMgmCallBack_p) (int, void *); +void ContMgmLoad (wIcon_p,contMgmCallBack_p,void *); + /* doption.c */ long GetDistanceFormat( void ); @@ -382,10 +395,21 @@ void ClearCars( void ); void CarDlgAddProto( void ); void CarDlgAddDesc( void ); void AttachTrains( void ); -#endif + /* cblock.c */ void InitCmdBlock( wMenu_p menu ); - +void BlockMgmLoad( void ); /* cswitchmotor.c */ void InitCmdSwitchMotor( wMenu_p menu ); +void SwitchmotorMgmLoad( void ); +/* csignal.c */ +void InitCmdSignal ( wMenu_p menu ); +void SignalMgmLoad ( void ); +/* ccontrol.c */ +void ControlMgmLoad ( void ); +void InitCmdControl ( wMenu_p menu ); +/* csensor.c */ +void SensorMgmLoad ( void ); +void InitCmdSensor ( wMenu_p menu ); +#endif diff --git a/app/bin/misc2.c b/app/bin/misc2.c index 1013179..2c7644b 100644 --- a/app/bin/misc2.c +++ b/app/bin/misc2.c @@ -45,7 +45,7 @@ #include "compound.h" #include "i18n.h" -EXPORT long units = 0; +EXPORT long units = 0; /**< measurement units: 0 = English, 1 = metric */ EXPORT long checkPtInterval = 10; EXPORT DIST_T curScaleRatio; diff --git a/app/bin/param.c b/app/bin/param.c index f5ae69f..27c558f 100644 --- a/app/bin/param.c +++ b/app/bin/param.c @@ -72,96 +72,6 @@ static int hotspotOffsetY = 19; static int log_paramLayout; -#ifdef LATER -/***************************************************************************** - * - * Colors - * - */ - -typedef struct { - long rgb; - char * name; - wDrawColor color; - } colorTab_t[]; - -static colorTab_t colorTab = { - { wRGB( 0, 0, 0), N_("Black") }, - - { wRGB( 0, 0,128), N_("Dark Blue") }, - { wRGB( 70,130,180), N_("Steel Blue") }, - { wRGB( 65,105,225), N_("Royal Blue") }, - { wRGB( 0, 0,255), N_("Blue") }, - { wRGB( 0,191,255), N_("Deep Sky Blue") }, - { wRGB(125,206,250), N_("Light Sky Blue") }, - { wRGB(176,224,230), N_("Powder Blue") }, - - { wRGB( 0,128,128), N_("Dark Aqua") }, - { wRGB(127,255,212), N_("Aquamarine") }, - { wRGB( 0,255,255), N_("Aqua") }, - - { wRGB( 0,128, 0), N_("Dark Green") }, - { wRGB( 34,139, 34), N_("Forest Green") }, - { wRGB( 50,205, 50), N_("Lime Green") }, - { wRGB( 0,255, 0), N_("Green") }, - { wRGB(124,252, 0), N_("Lawn Green") }, - { wRGB(152,251,152), N_("Pale Green") }, - - { wRGB(128,128, 0), N_("Dark Yellow") }, - { wRGB(255,127, 80), N_("Coral") }, - { wRGB(255,165, 0), N_("Orange") }, - { wRGB(255,215, 0), N_("Gold") }, - { wRGB(255,255, 0), N_("Yellow") }, - - { wRGB(139, 69, 19), N_("Saddle Brown") }, - { wRGB(165, 42, 42), N_("Brown") }, - { wRGB(210,105, 30), N_("Chocolate") }, - { wRGB(188,143,143), N_("Rosy Brown") }, - { wRGB(210,180,140), N_("Tan") }, - { wRGB(245,245,220), N_("Beige") }, - - - { wRGB(128, 0, 0), N_("Dark Red") }, - { wRGB(255, 99, 71), N_("Tomato") }, - { wRGB(255, 0, 0), N_("Red") }, - { wRGB(255,105,180), N_("Hot Pink") }, - { wRGB(255,192,203), N_("Pink") }, - - { wRGB(128, 0,128), N_("Dark Purple") }, - { wRGB(176, 48, 96), N_("Maroon") }, - { wRGB(160, 32,240), N_("Purple2") }, - { wRGB(255, 0,255), N_("Purple") }, - { wRGB(238,130,238), N_("Violet") }, - - { wRGB( 64, 64, 64), N_("Dark Gray") }, - { wRGB(128,128,128), N_("Gray") }, - { wRGB(192,192,192), N_("Light Gray") } }; -static wIcon_p colorTabBitMaps[ sizeof colorTab/sizeof colorTab[0] ]; -#include "bitmaps/square10.xbm" - -static BOOL_T colorTabInitted = FALSE; - -static void InitColorTab( void ) -{ - wIndex_t inx; - for ( inx=0; inx<COUNT(colorTab); inx++ ) - colorTab[inx].color = wDrawFindColor( colorTab[inx].rgb ); - colorTabInitted = TRUE; -} - - -static wIndex_t ColorTabLookup( wDrawColor color ) -{ - wIndex_t inx; - if (!colorTabInitted) - InitColorTab(); - for (inx = 0; inx < sizeof colorTab/sizeof colorTab[0]; inx++ ) - if (colorTab[inx].color == color) - return inx; - return 0; -} -#endif - /***************************************************************************** * * @@ -613,10 +523,6 @@ EXPORT void ParamLoadControl( p->oldD.l = *(wIndex_t*)p->valueP; break; case PD_COLORLIST: -#ifdef LATER - inx = ColorTabLookup( *(wDrawColor*)p->valueP ); - wListSetIndex( (wList_p)p->control, inx ); -#endif wColorSelectButtonSetColor( (wButton_p)p->control, *(wDrawColor*)p->valueP ); p->oldD.dc = *(wDrawColor*)p->valueP; break; @@ -736,10 +642,6 @@ EXPORT long ParamUpdate( break; case PD_COLORLIST: dc = wColorSelectButtonGetColor( (wButton_p)p->control ); -#ifdef LATER - inx = wListGetIndex( (wList_p)p->control ); - dc = colorTab[inx].color; -#endif if (dc != p->oldD.dc) { p->oldD.dc = dc; if ( /*(p->option&PDO_NOUPDUPD)==0 &&*/ p->valueP) @@ -830,10 +732,6 @@ EXPORT void ParamLoadData( break; case PD_COLORLIST: *(wDrawColor*)p->valueP = wColorSelectButtonGetColor( (wButton_p)p->control ); -#ifdef LATER - inx = wListGetIndex( (wList_p)p->control ); - *(wDrawColor*)p->valueP = colorTab[inx].color; -#endif break; case PD_FLOAT: if (p->option & PDO_DIM) { @@ -1380,7 +1278,7 @@ static void ParamIntegerPush( const char * val, void * dp ) while ( isspace((unsigned char)*val)) val++; valL = strtol( val, &cp, 10 ); - wControlSetBalloon( p->control, 0, -5, NULL ); + //wControlSetBalloon( p->control, 0, -5, NULL ); if ( val == cp ) { wControlSetBalloon( p->control, 0, -5, _("Invalid Number") ); return; @@ -1432,7 +1330,7 @@ static void ParamFloatPush( const char * val, void * dp ) if (p->option & PDO_ANGLE) valF = NormalizeAngle( (angleSystem==ANGLE_POLAR)?valF:-valF ); } - wControlSetBalloon( p->control, 0, -5, NULL ); + // wControlSetBalloon( p->control, 0, -5, NULL ); if ( !valid ) { wControlSetBalloon( p->control, 0, -5, decodeErrorStr ); return; @@ -1500,22 +1398,7 @@ static void ParamListPush( wIndex_t inx, const char * val, wIndex_t op, void * d p->group->changeProc( p->group, p-p->group->paramPtr, &valL ); } break; -#ifdef LATER - case PD_COLORLIST: - dc = colorTab[inx].color; - rgb = wDrawGetRGB( dc ); - if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) { - fprintf( recordF, "PARAMETER %s %s %ld\n", - p->group->nameStr, p->nameStr, rgb ); - fflush( recordF ); - } - if ( (p->option&PDO_NOPSHUPD)==0 && p->valueP) - *(wDrawColor*)(p->valueP) = dc; - if ( (p->option&PDO_NOPSHACT)==0 && p->group->changeProc ) { - ; /* COLOR NOP */ - } - break; -#endif + default: ; } @@ -1644,10 +1527,6 @@ EXPORT void ParamChange( paramData_p p ) case PD_COLORLIST: if (recordF && (p->option&PDO_NORECORD)==0 && p->group->nameStr && p->nameStr) fprintf( recordF, "PARAMETER %s %s %ld\n", p->group->nameStr, p->nameStr, rgb ); -#ifdef LATER - if ( p->control && (p->option&PDO_NOCONTUPD) == 0 ) - wColorSelectButtonSetColor( (wButton_p)p->control, wDrawFindRGB(rgb) ); -#endif break; case PD_FLOAT: tmpR = *(FLOAT_T*)p->valueP; @@ -1842,13 +1721,6 @@ static void ParamPlayback( char * line ) dc = wDrawFindColor( rgb ); if ( p->control) wColorSelectButtonSetColor( (wButton_p)p->control, dc ); -#ifdef LATER - valL = ColorTabLookup( dc ); - if (p->control) { - wListSetIndex( (wList_p)p->control, (wIndex_t)valL ); - wFlush(); - } -#endif if (p->valueP) *(wDrawColor*)p->valueP = dc; if (pg->changeProc) { diff --git a/app/bin/track.c b/app/bin/track.c index 30ea186..bbbf48a 100644 --- a/app/bin/track.c +++ b/app/bin/track.c @@ -923,7 +923,7 @@ EXPORT void ResolveIndex( void ) { track_p trk; EPINX_T ep; - TRK_ITERATE(trk) + TRK_ITERATE(trk) { for (ep=0; ep<trk->endCnt; ep++) if (trk->endPt[ep].index >= 0) { trk->endPt[ep].track = FindTrack( trk->endPt[ep].index ); @@ -931,6 +931,9 @@ EXPORT void ResolveIndex( void ) NoticeMessage( MSG_RESOLV_INDEX_BAD_TRK, _("Continue"), NULL, trk->index, ep, trk->endPt[ep].index ); } } + ResolveBlockTrack (trk); + ResolveSwitchmotorTurnout (trk); + } AuditTracks( "readTracks" ); } @@ -966,6 +969,8 @@ LOG( log_track, 4, ( "DeleteTrack(T%d)\n", GetTrkIndex(trk) ) ) ClrTrkElev( trk2 ); } } + CheckDeleteSwitchmotor( trk ); + CheckDeleteBlock( trk ); UndoDelete( trk ); MainRedraw(); trackCount--; diff --git a/app/bin/track.h b/app/bin/track.h index 81f5e4c..e26a47a 100644 --- a/app/bin/track.h +++ b/app/bin/track.h @@ -42,8 +42,6 @@ #include "misc.h" - - extern TRKTYP_T T_NOTRACK; struct track_t ; @@ -650,5 +648,12 @@ void AddHotBarTurnouts( void ); void AddHotBarStructures( void ); void AddHotBarCarDesc( void ); +/* cblock.c */ +void CheckDeleteBlock( track_p t ); +void ResolveBlockTrack ( track_p trk ); +/* cswitchmotor.c */ +void CheckDeleteSwitchmotor( track_p t ); +void ResolveSwitchmotorTurnout ( track_p trk ); + #endif diff --git a/app/bin/unittest/CMakeLists.txt b/app/bin/unittest/CMakeLists.txt new file mode 100644 index 0000000..b6d2bc5 --- /dev/null +++ b/app/bin/unittest/CMakeLists.txt @@ -0,0 +1,12 @@ +# build unit tests for the xtrkcad library + +add_executable(dxfformattest + dxfformattest.c + ../dxfformat.c + ) + +target_link_libraries(dxfformattest + dynstring + ${LIBS}) + +add_test(DXFOutputTest dxfformattest)
\ No newline at end of file diff --git a/app/bin/unittest/dxfformattest.c b/app/bin/unittest/dxfformattest.c new file mode 100644 index 0000000..b797ad9 --- /dev/null +++ b/app/bin/unittest/dxfformattest.c @@ -0,0 +1,144 @@ +/** \file DynStringTest.c +* Unit tests for the dxfformat module +*/ + +#include <stdarg.h> +#include <stddef.h> +#include <string.h> +#include <stdio.h> +#include <setjmp.h> +#include <cmocka.h> + +#include <dynstring.h> +#include <dxfformat.h> + +char *sProdNameUpper = "XTRKCAD"; +long units; + +static void BasicFormatting(void **state) +{ + DynString string; + (void)state; + + DynStringMalloc(&string, 0); + + DxfLayerName(&string, sProdNameUpper, 0); + assert_string_equal(DynStringToCStr(&string), DXF_INDENT "8\nXTRKCAD0\n"); + + DxfLayerName(&string, sProdNameUpper, 99); + assert_string_equal(DynStringToCStr(&string), DXF_INDENT "8\nXTRKCAD99\n"); + + DxfFormatPosition(&string, 20, 1); + assert_string_equal(DynStringToCStr(&string), DXF_INDENT "20\n1.000000\n"); + + DxfFormatPosition(&string, 20, 1.23456789); + assert_string_equal(DynStringToCStr(&string), DXF_INDENT "20\n1.234568\n"); + + DxfFormatPosition(&string, 20, 1.23456712); + assert_string_equal(DynStringToCStr(&string), DXF_INDENT "20\n1.234567\n"); +} + +static void LineCommand(void **state) +{ + DynString string; + (void)state; + + DynStringMalloc(&string, 0); + + DxfLineCommand( &string, 0, 1.0, 2.0, 1.1, 2.2, 1); + assert_string_equal(DynStringToCStr(&string), + DXF_INDENT "0\nLINE\n 8\nXTRKCAD0\n 10\n1.000000\n 20\n2.000000\n 11\n1.100000\n 21\n2.200000\n 6\nDASHED\n"); + + DynStringFree(&string); +} + + +static void CircleCommand(void **state) +{ + DynString string; + (void)state; + + DynStringMalloc(&string, 0); + + DxfCircleCommand(&string, 0, 1.0, 2.0, 1.1, 1); + assert_string_equal(DynStringToCStr(&string), + DXF_INDENT "0\nCIRCLE\n 10\n1.000000\n 20\n2.000000\n 40\n1.100000\n 8\nXTRKCAD0\n 6\nDASHED\n"); + + DynStringFree(&string); +} + + +static void ArcCommand(void **state) +{ + DynString string; + (void)state; + + DynStringMalloc(&string, 0); + + DxfArcCommand(&string, 0, 1.0, 2.0, 1.1, 10.0, 180.0, 1); + assert_string_equal(DynStringToCStr(&string), + DXF_INDENT "0\nARC\n 10\n1.000000\n 20\n2.000000\n 40\n1.100000\n 50\n10.000000\n 51\n190.000000\n 8\nXTRKCAD0\n 6\nDASHED\n"); + + DynStringFree(&string); +} + +#define TESTSTRING "This is a dxf test string" + +static void TextCommand(void **state) +{ + DynString string; + (void)state; + + DynStringMalloc(&string, 0); + + DxfTextCommand(&string, 0, 10.0, 12.0, 144.0, TESTSTRING); + + assert_string_equal(DynStringToCStr(&string), + DXF_INDENT "0\nTEXT\n 1\n" TESTSTRING "\n 10\n10.000000\n 20\n12.000000\n 40\n2.000000\n 8\nXTRKCAD0\n"); + + DynStringFree(&string); +} + +static void Units(void **state) +{ + DynString string; + (void)state; + + DynStringMalloc(&string, 0); + + /* test English units */ + units = 0; + DxfUnits(&string); + assert_string_equal(DynStringToCStr(&string), DXF_INDENT "9\n$MEASUREMENT\n 70\n0\n" DXF_INDENT "9\n$INSUNITS\n 70\n1\n"); + DxfFormatPosition(&string, 20, 1.23456789); + assert_string_equal(DynStringToCStr(&string), DXF_INDENT "20\n1.234568\n"); + + DynStringClear(&string); + DxfDimensionSize(&string, DXF_DIMTEXTSIZE); + assert_string_equal(DynStringToCStr(&string), DXF_INDENT "9\n$DIMTXT\n 40\n1.0\n"); + + /* test metric units */ + units = 1; + DynStringClear(&string); + DxfUnits(&string); + assert_string_equal(DynStringToCStr(&string), DXF_INDENT "9\n$MEASUREMENT\n 70\n1\n" DXF_INDENT "9\n$INSUNITS\n 70\n4\n"); + DxfFormatPosition(&string, 20, 1.23456789); + assert_string_equal(DynStringToCStr(&string), DXF_INDENT "20\n31.358024\n"); + + DynStringClear(&string); + DxfDimensionSize(&string, DXF_DIMTEXTSIZE); + assert_string_equal(DynStringToCStr(&string), DXF_INDENT "9\n$DIMTXT\n 40\n25.0\n"); + +} +int main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(BasicFormatting), + cmocka_unit_test(LineCommand), + cmocka_unit_test(CircleCommand), + cmocka_unit_test(ArcCommand), + cmocka_unit_test(TextCommand), + cmocka_unit_test(Units) + }; + return cmocka_run_group_tests(tests, NULL, NULL); +}
\ No newline at end of file |