summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.hgignore7
-rw-r--r--.hgtags16
-rw-r--r--CMake/FindCMocka.cmake51
-rw-r--r--CMakeLists.txt17
-rw-r--r--app/CMakeLists.txt2
-rw-r--r--app/bin/CMakeLists.txt23
-rw-r--r--app/bin/acclkeys.h1
-rw-r--r--app/bin/bitmaps/block.xpm24
-rw-r--r--app/bin/bitmaps/blockdel.xpm52
-rw-r--r--app/bin/bitmaps/blockedit.xpm89
-rw-r--r--app/bin/bitmaps/blocknew.xpm90
-rw-r--r--app/bin/bitmaps/control.xpm24
-rw-r--r--app/bin/bitmaps/sensor.xpm22
-rw-r--r--app/bin/bitmaps/signal.xpm25
-rw-r--r--app/bin/bitmaps/square10.xbm7
-rw-r--r--app/bin/bitmaps/switchm.xpm30
-rw-r--r--app/bin/bitmaps/switchmdel.xpm54
-rw-r--r--app/bin/bitmaps/switchmedit.xpm78
-rw-r--r--app/bin/bitmaps/switchmnew.xpm66
-rw-r--r--app/bin/bitmaps/switchmotormark.xbm6
-rw-r--r--app/bin/cblock.c367
-rw-r--r--app/bin/ccontrol.c597
-rw-r--r--app/bin/cdraw.c156
-rw-r--r--app/bin/cmisc.c1
-rw-r--r--app/bin/cmodify.c8
-rw-r--r--app/bin/cprofile.c13
-rw-r--r--app/bin/csensor.c561
-rw-r--r--app/bin/csignal.c885
-rw-r--r--app/bin/cswitchmotor.c348
-rw-r--r--app/bin/ctext.c69
-rw-r--r--app/bin/cundo.c2
-rw-r--r--app/bin/custom.c5
-rw-r--r--app/bin/custom.h3
-rw-r--r--app/bin/dcontmgm.c312
-rw-r--r--app/bin/dprmfile.c2
-rw-r--r--app/bin/draw.c2
-rw-r--r--app/bin/draw.h1
-rw-r--r--app/bin/dxfformat.c368
-rw-r--r--app/bin/dxfformat.h26
-rw-r--r--app/bin/dxfoutput.c230
-rw-r--r--app/bin/fileio.c193
-rw-r--r--app/bin/helphelper.c146
-rw-r--r--app/bin/misc.c14
-rw-r--r--app/bin/misc.h28
-rw-r--r--app/bin/misc2.c2
-rw-r--r--app/bin/param.c134
-rw-r--r--app/bin/track.c7
-rw-r--r--app/bin/track.h9
-rw-r--r--app/bin/unittest/CMakeLists.txt12
-rw-r--r--app/bin/unittest/dxfformattest.c144
-rw-r--r--app/doc/CMakeLists.txt34
-rw-r--r--app/doc/addm.but131
-rw-r--r--app/doc/appendix.but41
-rw-r--r--app/doc/changem.but2
-rw-r--r--app/doc/drawm.but2
-rw-r--r--app/doc/editm.but1
-rw-r--r--app/doc/filem.but2
-rw-r--r--app/doc/helpm.but1
-rw-r--r--app/doc/hotbar.but1
-rw-r--r--app/doc/intro.but.in10
-rw-r--r--app/doc/linconf.but4
-rw-r--r--app/doc/macrom.but1
-rw-r--r--app/doc/managem.but35
-rw-r--r--app/doc/navigation.but1
-rw-r--r--app/doc/optionm.but1
-rw-r--r--app/doc/osxconf.but16
-rw-r--r--app/doc/png.d/bblock.pngbin0 -> 713 bytes
-rw-r--r--app/doc/png.d/bcontrol.pngbin0 -> 619 bytes
-rw-r--r--app/doc/png.d/block.pngbin0 -> 18245 bytes
-rw-r--r--app/doc/png.d/bsensor.pngbin0 -> 563 bytes
-rw-r--r--app/doc/png.d/bsignal.pngbin0 -> 581 bytes
-rw-r--r--app/doc/png.d/bswitchmotor.pngbin0 -> 679 bytes
-rw-r--r--app/doc/png.d/control.pngbin0 -> 12729 bytes
-rw-r--r--app/doc/png.d/lcemanager.pngbin0 -> 35289 bytes
-rw-r--r--app/doc/png.d/madd.pngbin3690 -> 7895 bytes
-rw-r--r--app/doc/png.d/mmanage.pngbin4860 -> 8632 bytes
-rw-r--r--app/doc/png.d/sensor.pngbin0 -> 11777 bytes
-rw-r--r--app/doc/png.d/signal.pngbin0 -> 30230 bytes
-rw-r--r--app/doc/png.d/switchmotor.pngbin0 -> 22300 bytes
-rw-r--r--app/doc/statusbar.but1
-rw-r--r--app/doc/upgrade.but3
-rw-r--r--app/doc/view_winm.but1
-rw-r--r--app/doc/warranty.but3
-rw-r--r--app/doc/xtrkcad_osx.css144
-rw-r--r--app/dynstring/CMakeLists.txt11
-rw-r--r--app/dynstring/dynstring.c457
-rw-r--r--app/dynstring/dynstring.h40
-rw-r--r--app/dynstring/unittest/CMakeLists.txt8
-rw-r--r--app/dynstring/unittest/DynStringTest.c108
-rw-r--r--app/help/genhelp.in15
-rw-r--r--app/help/xtrkcad.info16
-rw-r--r--app/i18n/de_DE.po165
-rw-r--r--app/i18n/fi.po2
-rw-r--r--app/i18n/pt_BR.po2
-rw-r--r--app/lib/CMakeLists.txt11
-rw-r--r--app/lib/Readme.md68
-rw-r--r--app/lib/Readme.txt1051
-rw-r--r--app/lib/astylerc8
-rw-r--r--app/lib/params/HO-Frateschi.xtp196
-rw-r--r--app/lib/params/HOn3-BlackStoneProTraxx.xtp21
-rw-r--r--app/lib/params/Lego-Track.xtp152
-rw-r--r--app/lib/params/S-MTH S-Trax.xtp156
-rw-r--r--app/lib/params/S-SHelper S-Trax.xtp200
-rw-r--r--app/lib/params/TT-Kuehn.xtp6
-rw-r--r--app/lib/params/TTi-AuhagenNG.xtp40
-rw-r--r--app/lib/params/TilligAdvTT.xtp627
-rw-r--r--app/lib/params/atl83ho.xtp8
-rw-r--r--app/lib/params/pecoho83.xtp271
-rw-r--r--app/lib/xtrkcad.desktop4
-rw-r--r--app/lib/xtrkcad.png (renamed from app/lib/icon.png)bin3803 -> 3803 bytes
-rw-r--r--app/lib/xtrkcad.xtq4
-rw-r--r--app/tools/halibut/bk_html.c185
-rw-r--r--app/tools/halibut/halibut.h1
-rw-r--r--app/tools/halibut/input.c3
-rw-r--r--app/wlib/gtklib/CMakeLists.txt56
-rw-r--r--app/wlib/gtklib/bitmap.c136
-rw-r--r--app/wlib/gtklib/boxes.c203
-rw-r--r--app/wlib/gtklib/button.c630
-rw-r--r--app/wlib/gtklib/color.c466
-rw-r--r--app/wlib/gtklib/control.c283
-rw-r--r--app/wlib/gtklib/droplist.c456
-rw-r--r--app/wlib/gtklib/dynarr.h5
-rw-r--r--app/wlib/gtklib/filesel.c43
-rw-r--r--app/wlib/gtklib/font.c403
-rw-r--r--app/wlib/gtklib/gtkbitmap.c85
-rw-r--r--app/wlib/gtklib/gtkbutton.c461
-rw-r--r--app/wlib/gtklib/gtkcolor.c476
-rw-r--r--app/wlib/gtklib/gtkdraw-cairo.c138
-rw-r--r--app/wlib/gtklib/gtkfont.c342
-rw-r--r--app/wlib/gtklib/gtkhelp.c733
-rw-r--r--app/wlib/gtklib/gtkint.h263
-rw-r--r--app/wlib/gtklib/gtklist.c1131
-rw-r--r--app/wlib/gtklib/gtkmenu.c873
-rw-r--r--app/wlib/gtklib/gtkmisc.c1210
-rw-r--r--app/wlib/gtklib/gtksimple.c366
-rw-r--r--app/wlib/gtklib/gtksingle.c645
-rw-r--r--app/wlib/gtklib/gtksplash.c142
-rw-r--r--app/wlib/gtklib/gtktext.c670
-rw-r--r--app/wlib/gtklib/gtkwindow.c856
-rw-r--r--app/wlib/gtklib/gtkxpm.c173
-rw-r--r--app/wlib/gtklib/help.c69
-rw-r--r--app/wlib/gtklib/ixhelp.c441
-rw-r--r--app/wlib/gtklib/lines.c150
-rw-r--r--app/wlib/gtklib/list.c547
-rw-r--r--app/wlib/gtklib/liststore.c267
-rw-r--r--app/wlib/gtklib/main.c107
-rw-r--r--app/wlib/gtklib/menu.c1084
-rw-r--r--app/wlib/gtklib/message.c168
-rw-r--r--app/wlib/gtklib/notice.c297
-rw-r--r--app/wlib/gtklib/osxhelp.c133
-rw-r--r--app/wlib/gtklib/pixbuf.c99
-rw-r--r--app/wlib/gtklib/png.c64
-rw-r--r--app/wlib/gtklib/print.c1000
-rw-r--r--app/wlib/gtklib/single.c335
-rw-r--r--app/wlib/gtklib/splash.c144
-rw-r--r--app/wlib/gtklib/square10.bmp8
-rw-r--r--app/wlib/gtklib/text.c590
-rw-r--r--app/wlib/gtklib/timer.c144
-rw-r--r--app/wlib/gtklib/tooltip.c255
-rw-r--r--app/wlib/gtklib/treeview.c530
-rw-r--r--app/wlib/gtklib/util.c672
-rw-r--r--app/wlib/gtklib/window.c936
-rw-r--r--app/wlib/gtklib/wpref.c128
-rw-r--r--app/wlib/include/wlib.h174
-rw-r--r--app/wlib/mswlib/mswedit.c2
-rw-r--r--app/wlib/mswlib/mswmisc.c2
-rw-r--r--distribution/osx/CMakeLists.txt51
-rw-r--r--distribution/osx/bundle/Info.plist.in4
-rw-r--r--distribution/osx/gtk-bundle/CMakeLists.txt20
-rw-r--r--distribution/osx/gtk-bundle/Drag-to-Copy-Arrow.pngbin0 -> 2171 bytes
-rw-r--r--distribution/osx/gtk-bundle/XTrackCAD-help/CMakeLists.txt14
-rw-r--r--distribution/osx/gtk-bundle/XTrackCAD-help/Contents/CMakeLists.txt5
-rw-r--r--distribution/osx/gtk-bundle/XTrackCAD-help/Contents/Resources/CMakeLists.txt12
-rw-r--r--distribution/osx/gtk-bundle/XTrackCAD-help/Contents/Resources/en.lproj/CMakeLists.txt10
-rw-r--r--distribution/osx/gtk-bundle/XTrackCAD-help/Contents/Resources/en.lproj/InfoPlist.strings2
-rw-r--r--distribution/osx/gtk-bundle/XTrackCAD-help/Contents/Resources/icon_16x16.pngbin0 -> 673 bytes
-rw-r--r--distribution/osx/gtk-bundle/XTrackCAD-help/info-xtrkcad-help.plist.in36
-rw-r--r--distribution/osx/gtk-bundle/gtk-bundle.README44
-rw-r--r--distribution/osx/gtk-bundle/info-xtrkcad.plist34
-rw-r--r--distribution/osx/gtk-bundle/info-xtrkcad.plist.in34
-rw-r--r--distribution/osx/gtk-bundle/toc.js67
-rwxr-xr-xdistribution/osx/gtk-bundle/xtrkcad-bundler.sh84
-rwxr-xr-xdistribution/osx/gtk-bundle/xtrkcad-launcher.sh214
-rw-r--r--distribution/osx/gtk-bundle/xtrkcad-logo.icnsbin0 -> 1337741 bytes
-rw-r--r--distribution/osx/gtk-bundle/xtrkcad-template.dmg.zipbin0 -> 3990654 bytes
-rw-r--r--distribution/osx/gtk-bundle/xtrkcad.bundle132
-rw-r--r--distribution/posix/CMakeLists.txt2
-rw-r--r--distribution/posix/xtrkcad.spec4
-rw-r--r--docs/doxygen/Doxyfile.in3
-rw-r--r--notes12
-rw-r--r--xtrkcad-config.h.in1
191 files changed, 18818 insertions, 11158 deletions
diff --git a/.hgignore b/.hgignore
deleted file mode 100644
index 3404f26..0000000
--- a/.hgignore
+++ /dev/null
@@ -1,7 +0,0 @@
-# hg uses this global ignore file for all tree-wide ignores
-.DS_Store
-.project
-syntax: glob
-*.mo
-xtrkcad-4.2.3b.hg
-app/bin/dprmfile.c.orig
diff --git a/.hgtags b/.hgtags
deleted file mode 100644
index dc24381..0000000
--- a/.hgtags
+++ /dev/null
@@ -1,16 +0,0 @@
-94c2cf3d9771e319277a8d56c36be25957648f56 Release_4_0_3a
-882f15968b0abf4df60bf040e77f60286aac3bf4 Release_4_2_0beta1
-c07643cf9248a12e61cfbbfdc0ea443a8669d008 Release_4_2_0
-25dab80e5244b867c018381f34656ffba91d0e34 Release_4_2_1
-8485a3d22fbf500ddff7738cc263d884b8b2af0b Release_4_2_2
-5603bb19687491e39078eda424929d194909c48d Release_4_2_3
-3397423bf220a4dccdd4deb4c83faccad86e4bd2 Release_4_2_3a
-66aa9bf23b5beb89aa2590200e5de382b0fd3796 Release_4_2_3b
-66aa9bf23b5beb89aa2590200e5de382b0fd3796 Release_4_2_3b
-0000000000000000000000000000000000000000 Release_4_2_3b
-0000000000000000000000000000000000000000 Release_4_2_3b
-66aa9bf23b5beb89aa2590200e5de382b0fd3796 Release_4_2_3b
-19e42ff003fdf435c256041bb27c0a211917ee1e Release_4_2_4
-c0c1c81628cd366a1eb8f7ba081d06ea2688cdc5 Release_4_2_4a
-c0c1c81628cd366a1eb8f7ba081d06ea2688cdc5 Release_4_2_4a
-73cf3917555f849308dfe3fe16a4efc647fe841e Release_4_2_4a
diff --git a/CMake/FindCMocka.cmake b/CMake/FindCMocka.cmake
new file mode 100644
index 0000000..e8a4e92
--- /dev/null
+++ b/CMake/FindCMocka.cmake
@@ -0,0 +1,51 @@
+# - Try to find CMocka
+# Once done this will define
+#
+# CMOCKA_ROOT_DIR - Set this variable to the root installation of CMocka
+#
+# Read-Only variables:
+# CMOCKA_FOUND - system has CMocka
+# CMOCKA_INCLUDE_DIR - the CMocka include directory
+# CMOCKA_LIBRARIES - Link these to use CMocka
+# CMOCKA_DEFINITIONS - Compiler switches required for using CMocka
+#
+#=============================================================================
+# Copyright (c) 2011-2012 Andreas Schneider <asn@cryptomilk.org>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+#
+
+find_path(CMOCKA_INCLUDE_DIR
+ NAMES
+ cmocka.h
+ PATHS
+ ${CMOCKA_ROOT_DIR}/include
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Andreas Schneider\\cmocka]/include"
+)
+
+find_library(CMOCKA_LIBRARY
+ NAMES
+ cmocka
+ PATHS
+ ${CMOCKA_ROOT_DIR}/lib
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Andreas Schneider\\cmocka]/lib"
+)
+
+if (CMOCKA_LIBRARY)
+ set(CMOCKA_LIBRARIES
+ ${CMOCKA_LIBRARIES}
+ ${CMOCKA_LIBRARY}
+ )
+endif (CMOCKA_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(CMocka DEFAULT_MSG CMOCKA_LIBRARY CMOCKA_INCLUDE_DIR)
+
+# show the CMOCKA_INCLUDE_DIR and CMOCKA_LIBRARIES variables only in the advanced view
+mark_as_advanced(CMOCKA_INCLUDE_DIR CMOCKA_LIBRARY CMOCKA_LIBRARIES) \ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3db52bb..2f0a9a9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,10 @@
PROJECT(XTrkCAD)
+enable_testing()
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/app)
+# additional CMake modules can be found here
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake/")
# Setup high-level build options ...
IF(UNIX AND NOT APPLE)
@@ -71,6 +74,14 @@ IF(XTRKCAD_USE_PACKAGEMAKER)
ENDIF(NOT CMAKE_INSTALL_PREFIX STREQUAL "/usr")
ENDIF(XTRKCAD_USE_PACKAGEMAKER)
+# Find unit testing framework
+find_package(CMocka)
+if( CMOCKA_FOUND)
+ include_directories(${CMOCKA_INCLUDE_DIR})
+ set(LIBS ${LIBS} ${CMOCKA_LIBRARIES})
+ option( XTRKCAD_TESTING "Build unittests" ON)
+endif()
+
# Test for headers and libraries for portability ...
INCLUDE (CheckIncludeFiles)
@@ -78,9 +89,9 @@ CHECK_INCLUDE_FILES (malloc.h HAVE_MALLOC_H)
# Setup some global options for installation ...
SET(XTRKCAD_MAJOR_VERSION "4")
-SET(XTRKCAD_MINOR_VERSION "2")
-SET(XTRKCAD_RELEASE_VERSION "4")
-SET(XTRKCAD_VERSION_MODIFIER "a")
+SET(XTRKCAD_MINOR_VERSION "3")
+SET(XTRKCAD_RELEASE_VERSION "0")
+SET(XTRKCAD_VERSION_MODIFIER "")
SET(XTRKCAD_VERSION "${XTRKCAD_MAJOR_VERSION}.${XTRKCAD_MINOR_VERSION}.${XTRKCAD_RELEASE_VERSION}${XTRKCAD_VERSION_MODIFIER}")
IF(WIN32)
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index b237015..9a47f95 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -1,7 +1,9 @@
# "bin/i18n.h" is widely used
INCLUDE_DIRECTORIES(bin)
+include_directories(dynstring)
# Setup the rest of the build ...
+add_subdirectory(dynstring)
ADD_SUBDIRECTORY(wlib)
ADD_SUBDIRECTORY(tools)
ADD_SUBDIRECTORY(help)
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
diff --git a/app/doc/CMakeLists.txt b/app/doc/CMakeLists.txt
index dcee056..03ac14b 100644
--- a/app/doc/CMakeLists.txt
+++ b/app/doc/CMakeLists.txt
@@ -38,7 +38,11 @@ ADD_CUSTOM_TARGET(clean-html
# If we're using the GTK back-end, just generate "vanilla" HTML help files for use with gtkhtml
IF(XTRKCAD_USE_GTK)
- SET(HALIBUT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/linconf.but ${HALIBUT_SOURCES})
+ IF (APPLE)
+ SET(HALIBUT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/osxconf.but ${HALIBUT_SOURCES})
+ ELSE(APPLE)
+ SET(HALIBUT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/linconf.but ${HALIBUT_SOURCES})
+ ENDIF(APPLE)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/html/index.html
@@ -63,7 +67,31 @@ IF(XTRKCAD_USE_GTK)
INSTALL(
FILES xtrkcad_lin.css
DESTINATION ${XTRKCAD_SHARE_INSTALL_DIR}/html
- )
+ )
+# Copy the help files to the Help bundle if Apple
+ IF (APPLE)
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/html/XTrackCAD.helpindex
+ DEPENDS help-html ${HALIBUT_SOURCES}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html
+ COMMAND hiutil -Cf XTrackCAD.helpindex -gva -e "IndexPage.html" -e "toc.html" ${CMAKE_CURRENT_BINARY_DIR}/html
+ )
+
+ ADD_CUSTOM_TARGET(help-index ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/html/XTrackCAD.helpindex)
+
+ INSTALL(
+ DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
+ DESTINATION ${XTRKCAD_SHARE_INSTALL_DIR}/XTrackCAD.help/Contents/Resources/en.lproj
+ )
+ INSTALL(
+ DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/png.d
+ DESTINATION ${XTRKCAD_SHARE_INSTALL_DIR}/XTrackCAD.help/Contents/Resources/en.lproj
+ )
+ INSTALL(
+ FILES xtrkcad_osx.css
+ DESTINATION ${XTRKCAD_SHARE_INSTALL_DIR}/XTrackCAD.help/Contents/Resources/en.lproj
+ )
+ ENDIF(APPLE)
# Otherwise, we're using the Win32 back-end, so generate a compiled HTML help file
ELSE(XTRKCAD_USE_GTK)
@@ -86,7 +114,7 @@ ELSE(XTRKCAD_USE_GTK)
INSTALL(
FILES ${CMAKE_CURRENT_BINARY_DIR}/html/xtrkcad.chm
- DESTINATION ${XTRKCAD_SHARE_INSTALL_DIR}
+ DESTINATION ${XTRKCAD_SHARE_INSTALL_DIR}
)
ENDIF(XTRKCAD_USE_GTK)
diff --git a/app/doc/addm.but b/app/doc/addm.but
index 111b188..cee8896 100644
--- a/app/doc/addm.but
+++ b/app/doc/addm.but
@@ -6,8 +6,9 @@
\C{commandMenus} Command Menus
-\rule
+\cfg{html-local-head}{<meta name="AppleTitle" content="Command Menus" />}
+\rule
\H{addM}\i{Add Menu}
@@ -49,8 +50,25 @@ The \f{Add Menu} has all the actions related to adding track pieces to the layou
\dd \f{Turntable} - Place a turntable.
-\rule
+\u000
+
+\dd \f{Block} - Create, edit or delete a block.
+
+\u000
+
+\dd \f{Switchmotor} - Create, edit or delete a switchmotor.
+
+\u000
+
+\dd \f{Signal} - Create, edit or delete a signal.
+
+\u000
+\dd \f{Control} - Create a signal.
+
+\u000
+
+\dd \f{Sensor} - Create a sensor.
\S{cmdCircle} Circle Track
@@ -258,4 +276,111 @@ The \f{Modify command} (\K{cmdModify}) can be used to create turntable stall tra
The \f{Turntable Angle} control on the Preferences (\K{cmdPref}) dialog controls how closely you can place tracks connected to a turntable. If you want to create stall tracks every 7.5\u00B0, set the \f{Turntable Angle} control to 7.5 and place the track as close to each other as allowed. \e{XTrackCAD} makes sure they will be separated by the correct angle.
-\rule \ No newline at end of file
+\rule
+
+\S{cmdBlock} Block
+
+\G{png.d/bblock.png}
+
+A block is created by first selecting the track segments in the block and then
+selecting \f{Create Block} from either the Add menu \K{cmdAdd} or from the block menu on the
+hotbar. A block gets a name and a script. The name is only used for
+identification and the script is used by the layout control software. The
+script should provide whatever information is needed by the layout control
+software to determine block occupancy. This could be a code snippet to
+retrieve the state of the block occupancy or it could be the address of the
+sensor, etc.
+
+\G{png.d/block.png}
+
+The create block dialog has spaces for two text strings. One is the name and
+the other is a block occupancy script. The name identifies the block and the
+script is information used by the layout control software to detect block
+occupancy. The script could be a code snippet or I/O device address
+information, etc.
+
+\rule
+
+\S{cmdSwitchmotor} Switchmotor
+
+\G{png.d/bswitchmotor.png}
+
+A switchmotor is created by selecting \f{Create SwitchMotor} from either the Add
+menu \K{cmdAdd} or from the switchmotor menu on the hotbar and then clicking on a turnout.
+A switchmotor gets a name and three scripts. The name is only used for
+identification and the three scripts are used by the layout control software.
+The three scripts are for throwing the turnout to its "normal" position,
+throwing the turnout to its "reverse" position, and a script to read a point
+position sensor. These scripts could be code snippets or they could be
+addresses of I/O devices, etc.
+
+\G{png.d/switchmotor.png}
+
+The create switchmotor dialog has spaces for four text strings. One is the
+name and the other three are scripts for Normal, Reverse, and Point Sense. The
+name identifies the switchmotor and the scripts are information used by the
+layout control software to throw the turnout to the normal position, throw the
+turnout to the reverse position, and sense the point position. The scripts
+could be code snippets or I/O device address information, etc.
+
+\rule
+
+\S{cmdSignal} Signal
+
+\G{png.d/bsignal.png}
+
+A signal is created by selecting \f{Create Signal} from either the Add menu \K{cmdAdd} or
+from the hotbar. Use the mouse to select a location (left button) and then
+draging (left button down) the signal to set its orientation. Once the left
+button is released, a Create/Edit Signal dialog box is displayed, and you can
+fill in the signal's properties: name, fine tune the location and orientation,
+number of heads, and the aspects.
+
+\G{png.d/signal.png}
+
+The create/edit signal dialog has spaces for the name of the signal, its
+location and orientation, the number of heads (1, 2, or 3), and a list of
+aspects. Each aspect has a name and a script. The name could be a rule book
+name (Clear, Aproach, Stop, etc.) or the actual color(s) displayed (green,
+yellow, red, etc.). The script is just some information for the layout
+control software to actually effect the display of the aspect -- this could be
+the LCC event id to trigger the aspect or it could be a code snippet that
+causes the aspect to be displayed.
+
+\rule
+
+\S{cmdControl} Control
+
+\G{png.d/bControl.png}
+
+A control is created by selecting \f{Create Control} from either the Add menu \K{cmdAdd} or
+from the hotbar. Use the mouse to select a location (left button) and then
+dragging (left button down) the control to where you want it. Once the left
+button is released, a Create/Edit Control dialog box is displayed, and you can
+fill in the control's properties: name, fine tune the location, and the on and
+off scripts.
+
+\G{png.d/control.png}
+
+The create/edit control dialog has entry fields for the name of the control, its
+location, and a pair of scripts, one to turn the control on and one to turn
+the control off. The scripts are just some information for the layout control
+software to actually effect the state on the control (on or off).
+
+\rule
+
+\S{cmdSensor} Sensor
+
+\G{png.d/bSensor.png}
+
+A sensor is created by selecting \f{Create Sensor} from either the Add menu \K{cmdAdd} or
+from the hotbar. Use the mouse to select a location (left button) and then
+dragging (left button down) the sensor to where you want it. Once the left
+button is released, a Create/Edit Sensor dialog box is displayed, and you can
+fill in the sensor's properties: name, fine tune the location, and the script.
+
+\G{png.d/sensor.png}
+
+The create/edit sensor dialog has spaces for the name of the sensor, its
+location, and a script. The script is just some information for the layout
+control software to actually return the state of the sensor (on or off). \ No newline at end of file
diff --git a/app/doc/appendix.but b/app/doc/appendix.but
index 3155e38..2c16319 100644
--- a/app/doc/appendix.but
+++ b/app/doc/appendix.but
@@ -2,7 +2,7 @@
\#
\# The "\u000" command is used to format the output. These commands causes a blank line to appear between "bulleted" or "described" items.
\#
-
+\cfg{html-local-head}{<meta name="AppleTitle" content="Frequently Asked Questions" />}
\A{faqs} Frequently Asked Questions
@@ -209,6 +209,44 @@ Menu and sub-menu items are indicated by \e{File>Open}, which means select the \
\rule
+\H{controlElementScripts} Control Element Scripts and the Model RR System's Dispatcher
+
+Notes about control element scripts and the Model RR System's Dispatcher
+program in OpenLCB mode:
+
+When using the Model RR System's Dispatcher program in OpenLCB mode to create
+CTC panels, the panel elements can have their LCC event IDs automatically
+populated from the information in the XTrackCAD file, if the proper syntax is
+observed.
+
+A LCC event id is a 64-bit number, represented as eight pairs of hexadevimal
+digits (0-9, a-f/A-F) separated by periods (.). Each pair represents one 8-bit
+byte of the event id. This event id is either produced by a sensor or logic
+element or is consumed by a control/device or a logic element.
+
+For blocks the occupency script contains a pair of LCC event ids, separated by
+a colon (:). The first LCC event id is produced by the occupency detector
+when the train enters the block and the second LCC event id is produced by the
+occupency detector when the train leaves the block.
+
+For switchmotors the point sense script contains a pair of LCC event ids,
+separated by a colon (:). The first LCC event id is produced by the point
+sensor when the points are aligned in the "normal" position (typically aligned
+to the main) and the second LCC event id is produced by the point sensor when
+the points are aligned in the "reverse" position (typically aligned to the
+spur). The normal and reverse script each contain a signal LCC event id.
+These events are produced by the CTC Panel when the control point Code button
+is pressed (clicked) and are consumed by the switch motor.
+
+For signals, the aspect name is a space separated list of the color(s) of the
+signal heads from top to bottom and the aspect script is a LCC event id that
+is consumed to produce that aspect. Presumably, the LCC event id is produced
+by a logic element (presumably a mast group in a Tower-LCC or similar device)
+or virtual track circuit in a Tower-LCC or similar device.
+
+\rule
+
+
\A{} Messages and Explanations
\H{messageType} \i{Message Types}
@@ -236,3 +274,4 @@ Menu and sub-menu items are indicated by \e{File>Open}, which means select the \
\K{messageList} provides detail explanation of each information or error message.
\rule
+
diff --git a/app/doc/changem.but b/app/doc/changem.but
index 8327edf..2bcd90b 100644
--- a/app/doc/changem.but
+++ b/app/doc/changem.but
@@ -4,6 +4,8 @@
\#
\# The "\u00B0" command gives proper format to the degree sign.
+\cfg{html-local-head}{<meta name="AppleTitle" content="Change Menu" />}
+
\H{changeM}\i{Change Menu}
\G{png.d/mchange.png}
diff --git a/app/doc/drawm.but b/app/doc/drawm.but
index dd53418..21785ce 100644
--- a/app/doc/drawm.but
+++ b/app/doc/drawm.but
@@ -2,7 +2,7 @@
\#
\# The "\u000" command is used to format the output. The command causes a blank line to appear between "bulleted" or "described" items.
\#
-
+\cfg{html-local-head}{<meta name="AppleTitle" content="Draw Menu" />}
\H{cmdDraw} \i{Draw Menu}
diff --git a/app/doc/editm.but b/app/doc/editm.but
index 9572172..f31b6d6 100644
--- a/app/doc/editm.but
+++ b/app/doc/editm.but
@@ -2,6 +2,7 @@
\#
\# The "\u000" command is used to format the output. The command causes a blank line to appear between "bulleted" or "described" items.
\#
+\cfg{html-local-head}{<meta name="AppleTitle" content="Edit Menu" />}
\H{editM}\i{Edit Menu}
diff --git a/app/doc/filem.but b/app/doc/filem.but
index a47452e..8b74434 100644
--- a/app/doc/filem.but
+++ b/app/doc/filem.but
@@ -2,9 +2,11 @@
\#
\# The "\u000" command is used to format the output. The command causes a blank line to appear between "bulleted" or "described" items.
\#
+\cfg{html-local-head}{<meta name="AppleTitle" content="File Menu" />}
\H{fileM} \i{File Menu}
+
\G{png.d/mfile.png}
The \f{File Menu} shows file oriented commands for loading and saving layout files.
diff --git a/app/doc/helpm.but b/app/doc/helpm.but
index 290adf5..08ccd49 100644
--- a/app/doc/helpm.but
+++ b/app/doc/helpm.but
@@ -2,6 +2,7 @@
\#
\# The "\u000" command is used to format the output. The command causes a blank line to appear between "bulleted" or "described" items.
\#
+\cfg{html-local-head}{<meta name="AppleTitle" content="Help Menu" />}
\H{helpM} Help Menu
diff --git a/app/doc/hotbar.but b/app/doc/hotbar.but
index 3ce82f4..9683c5e 100644
--- a/app/doc/hotbar.but
+++ b/app/doc/hotbar.but
@@ -2,6 +2,7 @@
\#
\# The "\u000" command is used to format the output. The command causes a blank line to appear between "bulleted" or "described" items.
\#
+\cfg{html-local-head}{<meta name="AppleTitle" content="Hot Bar" />}
\H{cmdHotBar} Hot Bar
diff --git a/app/doc/intro.but.in b/app/doc/intro.but.in
index 3fe5b7e..cb0d0d2 100644
--- a/app/doc/intro.but.in
+++ b/app/doc/intro.but.in
@@ -44,7 +44,6 @@ Copyright 2007, Bob Blackwell and Martin Fischer
\IM{Created by Turnout Command}{Easements and Sectional Track} Sectional Track
-
\# >>>>>>>>>> Manual Begin's Here <<<<<<<<<<
\title \e{XTrackCAD} User's Manual
@@ -57,9 +56,10 @@ Copyright 2007, Bob Blackwell and Martin Fischer
\rule
-
\C{index} Introduction To \e{XTrackCAD}
+\cfg{html-local-head}{<meta name="AppleTitle" content="org.xtrkcad.help" />}
+
\e{XTrackCAD} is a CAD (computer-aided design) program for designing Model Railroad layouts. \e{XTrackCAD} supports any scale, has libraries of popular brands of turnouts and sectional track (plus you add your own easily), can automatically use spiral transition curves when joining track and has extensive on-line help and demonstrations. \e{XTrackCAD} lets you manipulate track much like you would with actual flex-track to modify, extend and join tracks and turnouts. Additional features include tunnels, 'post-it' notes, on-screen ruler, parts list, 99 drawing layers, undo/redo commands, bench-work, 'Print to Bitmap', elevations, train simulation and car inventory.
Using it, you can
@@ -780,7 +780,7 @@ This section of the manual describes how and where to report a bug or seek an en
\S{bugs} Reporting \i{Bugs}
-If you encounter an unreported bug please submit detail regarding such to the \f{Bug Tracker} located at the \W{http://sourceforge.net/tracker/?group_id=151737&atid=781978}{\e{XTrackCAD} Fork Project Site}.
+If you encounter an unreported bug please submit detail regarding such to the \f{Bug Tracker} located at the \W{http://sourceforge.net/tracker/?group_id=151737&amp;atid=781978}{\e{XTrackCAD} Fork Project Site}.
\f{Be sure to provide the three basic elements of a bug report:} What you were doing at the time the bug occurred, what you expected to happen and what actually happened. This detail will help developers replicate the error, find and correct the offending code.
@@ -808,7 +808,7 @@ If you encounter an unreported bug please submit detail regarding such to the \f
\f{Always search the bug database first.} Advice so good, we'll repeat it twice. Always search the bug database first. The odds are good that if you've found a problem, someone else found it too. If you spend a few minutes of your time making sure that you're not filing a duplicate bug, that's a few more minutes someone can spend helping to fix that bug rather than sorting out duplicate bug reports.
-\f{If you don't understand an error message, ask for help.} Don't report an error message you don't understand as a bug. There are a lot of places you can ask for help in understanding what is going on before you can claim that an error message you do not understand is a bug. (Once you've understood the error message and have a good suggestion for a way to make the error message clearer, you might consider reporting it as a \W{http://sourceforge.net/tracker/?group_id=151737&atid=781981}{\e{XTrackCAD} Feature Request}).
+\f{If you don't understand an error message, ask for help.} Don't report an error message you don't understand as a bug. There are a lot of places you can ask for help in understanding what is going on before you can claim that an error message you do not understand is a bug. (Once you've understood the error message and have a good suggestion for a way to make the error message clearer, you might consider reporting it as a \W{http://sourceforge.net/tracker/?group_id=151737&amp;atid=781981}{\e{XTrackCAD} Feature Request}).
\f{Be brief, but don't leave any important details out.} This is a fine line to walk. But there are some general guidelines:
@@ -825,6 +825,6 @@ If you can recreate the problem the \f{Macro>Record} command can be used to reco
\S{enhancements} \i{Enhancement Requests}
-Suggestions for improvements are encouraged and welcome. Submit your suggestion to the \e{XTrackCAD} \f{Feature Tracker} located at the \W{http://sourceforge.net/tracker/?group_id=151737&atid=781981}{\e{XTrackCAD} Fork Project Site} or the \e{XTrackCAD} \f{Wikka Wish List} located at the \W{http://www.xtrkcad.org/Wikka/WishList}{\e{XTrackCAD} Wiki: WishList}.
+Suggestions for improvements are encouraged and welcome. Submit your suggestion to the \e{XTrackCAD} \f{Feature Tracker} located at the \W{http://sourceforge.net/tracker/?group_id=151737&amp;.atid=781981}{\e{XTrackCAD} Fork Project Site} or the \e{XTrackCAD} \f{Wikka Wish List} located at the \W{http://www.xtrkcad.org/Wikka/WishList}{\e{XTrackCAD} Wiki: WishList}.
\rule
diff --git a/app/doc/linconf.but b/app/doc/linconf.but
index c8de305..ffb2685 100644
--- a/app/doc/linconf.but
+++ b/app/doc/linconf.but
@@ -1,7 +1,7 @@
\cfg{html-leaf-level}{infinite}
\cfg{html-leaf-contains-contents}{false}
-\cfg{html-suppress-navlinks}{true}
-\cfg{html-suppress-address}{true}
+\cfg{html-suppress-navlinks}{false}
+\cfg{html-suppress-address}{false}
\cfg{html-contents-filename}{contents.html}
\cfg{html-template-filename}{%k.html}
diff --git a/app/doc/macrom.but b/app/doc/macrom.but
index 85fed13..7bf816c 100644
--- a/app/doc/macrom.but
+++ b/app/doc/macrom.but
@@ -2,6 +2,7 @@
\#
\# The "\u000" command is used to format the output. The command causes a blank line to appear between "bulleted" or "described" items.
\#
+\cfg{html-local-head}{<meta name="AppleTitle" content="Macro Menu" />}
\H{macroM} Macro Menu
diff --git a/app/doc/managem.but b/app/doc/managem.but
index 65a20c0..4a769db 100644
--- a/app/doc/managem.but
+++ b/app/doc/managem.but
@@ -3,6 +3,7 @@
\# The "\u000" command is used to format the output. These commands causes a blank line to appear between "bulleted" or "described" items.
\#
\# The "\u00B0" command gives proper format to the degree sign.
+\cfg{html-local-head}{<meta name="AppleTitle" content="Manage Menu" />}
\H{manageM}\i{Manage Menu}
@@ -18,6 +19,10 @@ The \f{Manage Menu} shows commands affecting the \f{Main Canvas} (\K{mainW}).
\u000
+\dd \f{Layout Control Elements} - display the \f{Layout Control Elements} (\K{cmdContmgm}) dialog to manipulate blocks, turnout motors and signals.
+
+\u000
+
\dd \f{Group} - creates a \f{Structure} or \f{Turnout} definition from the selected (\K{cmdSelect}) objects. See the \f{Group} command (\K{cmdGroup}) for details.
\u000
@@ -290,6 +295,36 @@ The \f{New} buttons invokes the Car (\K{cmdCarpart}) dialog to create a new \f{C
\rule
+\S{cmdContmgm} Layout Control Elements Dialog
+
+This dialog is used to manage layout control elements (blocks, switchmotors, and signals).
+
+Control Elements are elements related to layout control: blocks (occupancy
+detection), switchmotors (actuators to "throw" turnouts), signals, controls
+(other actuator or output devices), and sensors (other sensor or input
+devices). These elements don't relate to directly "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. XTrackCAD 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 that XTrackCAD 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.
+
+\G{png.d/lcemanager.png}
+
+The main part of this dialog contains a list of the currently defined layout
+control elements (blocks, switchmotors, signals, controls, and sensors),
+along with the tracks they relate to. These elements are added to the layout
+either from their Hotbar menus or from the Add menu.
+
+The \f{Edit} button allows for editing a control element. And the \f{Delete} button
+deletes the selected element(s).
+
\S{cmdGroup} Group Dialog
The \f{Group} command combines the selected (\K{cmdSelect}) Lines and Shapes (\K{cmdDraw}) to create structures (\K{cmdHotBar}). You can give the structure (\K{cmdHotBar}) a title consisting of Manufacturer, Description and Part Number on the \f{Group} dialog.
diff --git a/app/doc/navigation.but b/app/doc/navigation.but
index a11e4fa..66b0cc9 100644
--- a/app/doc/navigation.but
+++ b/app/doc/navigation.but
@@ -3,6 +3,7 @@
\# The "\u000" command is used to format the output. The command causes a blank line to appear between "bulleted" or "described" items.
\#
\# The "\u00B0" command gives proper format to the degree sign.
+\cfg{html-local-head}{<meta name="AppleTitle" content="Navigation" />}
\C{navigation} Navigation
diff --git a/app/doc/optionm.but b/app/doc/optionm.but
index e6d49e0..c7f00d9 100644
--- a/app/doc/optionm.but
+++ b/app/doc/optionm.but
@@ -3,6 +3,7 @@
\# The "\u000" command is used to format the output. The command causes a blank line to appear between "bulleted" or "described" items.
\#
\# The "\u00B0" command gives proper format to the degree sign.
+\cfg{html-local-head}{<meta name="AppleTitle" content="Options Menu" />}
\H{optionM}\i{Options Menu}
diff --git a/app/doc/osxconf.but b/app/doc/osxconf.but
new file mode 100644
index 0000000..8656f0e
--- /dev/null
+++ b/app/doc/osxconf.but
@@ -0,0 +1,16 @@
+\cfg{html-version}{xhtml1.0strict}
+\cfg{html-leaf-level}{infinite}
+\cfg{html-leaf-contains-contents}{false}
+\cfg{html-suppress-navlinks}{true}
+\cfg{html-suppress-address}{true}
+
+\cfg{html-contents-filename}{contents.html}
+\cfg{html-template-filename}{%k.html}
+\cfg{html-template-fragment}{%k}
+\cfg{html-applehelp-toc}{toc.html}
+
+\cfg{html-contents-depth}{0}{2}
+
+\cfg{html-head-end}{<link rel="stylesheet" type="text/css" href="xtrkcad_osx.css" /><script type="text/javascript" src="toc.js" ></script>}
+\cfg{html-body-start}{<div id="container"><div id="toc" data-include="toc.html"></div><div id="contents">}
+\cfg{html-body-end}{</div></div>} \ No newline at end of file
diff --git a/app/doc/png.d/bblock.png b/app/doc/png.d/bblock.png
new file mode 100644
index 0000000..ccd90d9
--- /dev/null
+++ b/app/doc/png.d/bblock.png
Binary files differ
diff --git a/app/doc/png.d/bcontrol.png b/app/doc/png.d/bcontrol.png
new file mode 100644
index 0000000..131bb94
--- /dev/null
+++ b/app/doc/png.d/bcontrol.png
Binary files differ
diff --git a/app/doc/png.d/block.png b/app/doc/png.d/block.png
new file mode 100644
index 0000000..598fdad
--- /dev/null
+++ b/app/doc/png.d/block.png
Binary files differ
diff --git a/app/doc/png.d/bsensor.png b/app/doc/png.d/bsensor.png
new file mode 100644
index 0000000..7d9834b
--- /dev/null
+++ b/app/doc/png.d/bsensor.png
Binary files differ
diff --git a/app/doc/png.d/bsignal.png b/app/doc/png.d/bsignal.png
new file mode 100644
index 0000000..f6b52f8
--- /dev/null
+++ b/app/doc/png.d/bsignal.png
Binary files differ
diff --git a/app/doc/png.d/bswitchmotor.png b/app/doc/png.d/bswitchmotor.png
new file mode 100644
index 0000000..68d9a4a
--- /dev/null
+++ b/app/doc/png.d/bswitchmotor.png
Binary files differ
diff --git a/app/doc/png.d/control.png b/app/doc/png.d/control.png
new file mode 100644
index 0000000..2097021
--- /dev/null
+++ b/app/doc/png.d/control.png
Binary files differ
diff --git a/app/doc/png.d/lcemanager.png b/app/doc/png.d/lcemanager.png
new file mode 100644
index 0000000..281c0c2
--- /dev/null
+++ b/app/doc/png.d/lcemanager.png
Binary files differ
diff --git a/app/doc/png.d/madd.png b/app/doc/png.d/madd.png
index 15a1426..f689ebe 100644
--- a/app/doc/png.d/madd.png
+++ b/app/doc/png.d/madd.png
Binary files differ
diff --git a/app/doc/png.d/mmanage.png b/app/doc/png.d/mmanage.png
index 931d065..8ea36f7 100644
--- a/app/doc/png.d/mmanage.png
+++ b/app/doc/png.d/mmanage.png
Binary files differ
diff --git a/app/doc/png.d/sensor.png b/app/doc/png.d/sensor.png
new file mode 100644
index 0000000..1217b3a
--- /dev/null
+++ b/app/doc/png.d/sensor.png
Binary files differ
diff --git a/app/doc/png.d/signal.png b/app/doc/png.d/signal.png
new file mode 100644
index 0000000..e4332a5
--- /dev/null
+++ b/app/doc/png.d/signal.png
Binary files differ
diff --git a/app/doc/png.d/switchmotor.png b/app/doc/png.d/switchmotor.png
new file mode 100644
index 0000000..7b4e73d
--- /dev/null
+++ b/app/doc/png.d/switchmotor.png
Binary files differ
diff --git a/app/doc/statusbar.but b/app/doc/statusbar.but
index 61af8fc..6390722 100644
--- a/app/doc/statusbar.but
+++ b/app/doc/statusbar.but
@@ -2,6 +2,7 @@
\#
\# The "\u000" command is used to format the output. The command causes a blank line to appear between "bulleted" or "described" items.
\#
+\cfg{html-local-head}{<meta name="AppleTitle" content="Status Bar" />}
\H{cmdStatusbar} Status Bar
diff --git a/app/doc/upgrade.but b/app/doc/upgrade.but
index a88f8ce..efd0908 100644
--- a/app/doc/upgrade.but
+++ b/app/doc/upgrade.but
@@ -2,6 +2,7 @@
\#
\# The "\u000" command is used to format the output. The command causes a blank line to appear between "bulleted" or "described" items.
\#
+\cfg{html-local-head}{<meta name="AppleTitle" content="Upgrades" />}
\A{upgrades} Upgrade From Earlier \e{XTrackCAD} Version
@@ -70,7 +71,7 @@ The wheel on a wheel mouse can now be used to zoom in and out on a layout design
\f{Internationalization}
-Internationalization or the ability to localize \e{XTrackCAD} for use with various languages was adopted during this version upgrade. \e{XTrackCAD} is now available with balloon help and daily tips written in US English, Finnish and German. The \e{XTrackCAD} development team welcomes anyone who wishes to volunteer with translation of various support files. Let them know by submitting an offer to assist to the \e{XTrackCAD} \f{Feature Tracker} located at the \W{http://sourceforge.net/tracker/?group_id=151737&atid=781981}{\e{XTrackCAD} Fork Project Site} or the \e{XTrackCAD} \f{Wikka Wish List} located at the \W{http://www.xtrkcad.org/Wikka/WishList}{\e{XTrackCAD} Wiki: WishList}.
+Internationalization or the ability to localize \e{XTrackCAD} for use with various languages was adopted during this version upgrade. \e{XTrackCAD} is now available with balloon help and daily tips written in US English, Finnish and German. The \e{XTrackCAD} development team welcomes anyone who wishes to volunteer with translation of various support files. Let them know by submitting an offer to assist to the \e{XTrackCAD} \f{Feature Tracker} located at the \W{http://sourceforge.net/tracker/?group_id=151737&amp;atid=781981}{\e{XTrackCAD} Fork Project Site} or the \e{XTrackCAD} \f{Wikka Wish List} located at the \W{http://www.xtrkcad.org/Wikka/WishList}{\e{XTrackCAD} Wiki: WishList}.
\f{Minor Fixes and Enhancements}
diff --git a/app/doc/view_winm.but b/app/doc/view_winm.but
index eecb843..47ec17b 100644
--- a/app/doc/view_winm.but
+++ b/app/doc/view_winm.but
@@ -2,6 +2,7 @@
\#
\# The "\u000" command is used to format the output. The command causes a blank line to appear between "bulleted" or "described" items.
\#
+\cfg{html-local-head}{<meta name="AppleTitle" content="View Menu" />}
\H{viewM} \i{View Menu}
diff --git a/app/doc/warranty.but b/app/doc/warranty.but
index 9c4e909..357a0cb 100644
--- a/app/doc/warranty.but
+++ b/app/doc/warranty.but
@@ -1,3 +1,5 @@
+\cfg{html-local-head}{<meta name="AppleTitle" content="Warranty" />}
+
\A{warrantyLicenseCopy} Warranty, License and Copying
\e{XTrackCAD} is \XTCCopyRight.
@@ -10,6 +12,7 @@ covered by the Creative Commons Attribution-ShareAlike 2.5 License Agreement.
\H{warranty} Warranty
+
\e{XTrackCAD} is provided "as is" without warranty of any kind, either express or implied, including, but not limited to warranties of merchantability or fitness for a particular purpose. In no event will Sillub Technology be liable for any damages, including incidental or consequential damages, arising out of the use of the program, even if advised of the possibility of such damages.
\rule
diff --git a/app/doc/xtrkcad_osx.css b/app/doc/xtrkcad_osx.css
new file mode 100644
index 0000000..9069eb8
--- /dev/null
+++ b/app/doc/xtrkcad_osx.css
@@ -0,0 +1,144 @@
+/************************************************************************************
+LINUX Help File colour and fonts are done here. Halibut controls margins, line spacing and indents.
+*************************************************************************************/
+
+BODY {
+ background: white;
+ font-family: "Trebuchet MS", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Tahoma, sans-serif;
+}
+
+A:link {
+ text-decoration: none;
+ color: #7DA1BF;
+ font-weight: bold;
+} /* unvisited link */
+
+A:visited {
+ text-decoration: none;
+ color: #1d4e89;
+ font-weight: bold;
+} /* visited links */
+
+A:active {
+ text-decoration: none;
+ font-weight: bold;
+ color: red;
+ } /* active links */
+
+a:hover {
+ text-decoration: underline;
+ color: #F69256;
+ }
+
+H1 {
+ text-align: left;
+ font-size: large;
+ font-style: italic;
+ font-weight: bold;
+ padding: 3px 6px;
+}
+
+H2 {
+ text-align: left;
+ font-size: medium;
+ font-style: italic;
+ font-weight: bold;
+ padding: 3px 6px;
+}
+
+H3 {
+ text-align: left;
+ font-size: small;
+ font-style: italic;
+ font-weight: bold;
+ padding: 3px 6px;
+}
+
+#container {
+ height: 100%;
+ width: 100%;
+ overflow: hidden;
+}
+
+#toc {
+ position: fixed;
+ top: 0px;
+ left: 0px;
+ bottom: 0px;
+ font-size: 25% small;
+ overflow-y: scroll;
+ width: 20%;
+}
+
+#contents {
+ top: 0px;
+ right: 0px;
+ bottom: 0px;
+ margin-left: 20%;
+ float: left;
+ font-size: 90%;
+ color: #333;
+ font-weight: normal;
+ overflow: auto;
+}
+
+UL.top_link {
+ list-style: none;
+ padding-left:0;
+}
+
+#toc UL {
+ list-style: none;
+ padding-left:1em;
+}
+
+#toc A:link {
+ font-size: 62%;
+ text-decoration: none;
+ color: #7DA1BF;
+}
+#toc A:active {
+ font_size: 62%;
+ text-decoration: none;
+ color: red;
+ } /* active links */
+/* Style the buttons that are used to open and close the accordion panel */
+button.accordion {
+ background-color: #eee;
+ color: #444;
+ cursor: pointer;
+ padding: 0px;
+ width: 20px%;
+ text-align: left;
+ border: none;
+ outline: none;
+ transition: 0.4s;
+}
+
+button.accordion:before {
+ content: '\02795'; /* Unicode character for "plus" sign (+) */
+ font-size: 62%;
+ color: #777;
+ float: left;
+ margin-left: 5px;
+}
+
+button.accordion.active:before {
+ content: "\2796"; /* Unicode character for "minus" sign (-) */
+}
+
+
+/* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */
+button.accordion.active, button.accordion:hover {
+ background-color: #ddd;
+}
+
+div.panel {
+ padding: 0 18px;
+ background-color: white;
+ max-height: 0;
+ overflow: hidden;
+ transition: max-height 0.2s ease-out;
+}
+
+
diff --git a/app/dynstring/CMakeLists.txt b/app/dynstring/CMakeLists.txt
new file mode 100644
index 0000000..b407805
--- /dev/null
+++ b/app/dynstring/CMakeLists.txt
@@ -0,0 +1,11 @@
+# compile the dynstring library
+
+set( SOURCES
+ dynstring.c )
+
+add_library(dynstring
+ ${SOURCES})
+
+if(XTRKCAD_TESTING)
+ add_subdirectory( unittest )
+endif(XTRKCAD_TESTING) \ No newline at end of file
diff --git a/app/dynstring/dynstring.c b/app/dynstring/dynstring.c
new file mode 100644
index 0000000..6f3159c
--- /dev/null
+++ b/app/dynstring/dynstring.c
@@ -0,0 +1,457 @@
+/** \file dynstring.c
+* Library for dynamic string functions
+*/
+
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#include <stdarg.h>
+#include <memory.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "dynstring.h"
+
+/**
+* Get the current length of the string
+*
+* \param s IN the dynamic string
+* \return the length of the string in bytes
+*/
+
+size_t DynStringSize(DynString *s)
+{
+ if (isnas(s)) {
+ return 0;
+ }
+
+ return s->size;
+}
+
+/* An initialized empty struct string */
+#define STRINIT() (DynStringMalloc(16))
+
+/**
+* Allocate memory for a string of the desired length. To optimize memory usage
+* a minimum length of 16 bytes is allocated. The allocated string has to be freed
+* using the DynStringFree() function.
+*
+* \param s IN pointer to DynString structure
+* \param size IN number of bytes to allocate
+* \return pointer to the DynString
+*/
+
+DynString *DynStringMalloc(DynString *s, size_t size)
+{
+ if (size < 16) {
+ size = 16;
+ }
+
+ s->s = malloc(size);
+ s->size = 0;
+ s->b_size = (size_t)(size | STR_FREEABLE );
+ return (s);
+}
+
+/**
+* Try to compact string memory by reallocating a buffer large enough for the current
+* string content.
+*
+* \param s IN the dynamic string
+*/
+
+void DynStringRealloc(DynString *s)
+{
+ char *buf;
+
+ /* Not a string? */
+ if (isnas(s)) {
+ return;
+ }
+
+ /* Can't realloc? */
+ if (!(s->b_size & STR_FREEABLE)) {
+ return;
+ }
+
+ /* Don't invoke undefined behaviour with realloc(x, 0) */
+ if (!s->size) {
+ free(s->s);
+ s->s = malloc(16);
+ s->b_size = (size_t)(16 | STR_FREEABLE);
+ } else {
+ /* Try to compact */
+ buf = realloc(s->s, s->size);
+
+ if (buf) {
+ s->s = buf;
+ }
+ s->b_size = (size_t)(s->size | STR_FREEABLE);
+ }
+}
+
+/**
+* Clear the dynamic string. Current content is deleted. The buffer is shrinked to the
+* minimum size.
+*
+* \param s IN the dynamic string
+*/
+
+void DynStringClear(DynString *s)
+{
+ /* Not a string? */
+ if (isnas(s))
+ {
+ return;
+ }
+
+ /* Can't realloc? */
+ if (!(s->b_size & STR_FREEABLE))
+ {
+ return;
+ }
+ s->size = 0;
+
+ DynStringRealloc(s);
+}
+/**
+* Resize the string for a minimum number of bytes. In order to optimize memory usage the
+* actually allocated block of memory can be larger than the requested size.
+* In case of an error, the string is set to NaS
+*
+* \param s IN OUT the string
+* \param size IN the requested new size
+*/
+
+void DynStringResize(DynString *s, size_t size)
+{
+ char *buf;
+ size_t bsize;
+
+ /* Are we not a string? */
+ if (isnas(s)) {
+ return;
+ }
+
+ /* Not resizable */
+ if (!(s->b_size & STR_FREEABLE)) {
+ DynString s2;
+
+ /* Don't do anything if we want to shrink */
+ if (size <= s->size) {
+ return;
+ }
+
+ /* Need to alloc a new string */
+ DynStringMalloc(&s2, size);
+ /* Copy into new string */
+ memcpy(s2.s, s->s, s->size);
+ /* Point to new string */
+ s->s = s2.s;
+ s->b_size = s2.b_size;
+ return;
+ }
+
+ /* Too big */
+ if (size & STR_FREEABLE) {
+ DynString nas = NaS;
+ free(s->s);
+ *s = nas;
+ return;
+ }
+
+ bsize = (size_t)(s->b_size - STR_FREEABLE);
+
+ /* Keep at least 16 bytes */
+ if (size < 16) {
+ size = 16;
+ }
+
+ /* Nothing to do? */
+ if ((4 * size > 3 * bsize) && (size <= bsize)) {
+ return;
+ }
+
+ /* Try to double size instead of using a small increment */
+ if ((size > bsize) && (size < bsize * 2)) {
+ size = bsize * 2;
+ }
+
+ /* Keep at least 16 bytes */
+ if (size < 16) {
+ size = 16;
+ }
+
+ buf = realloc(s->s, size);
+
+ if (!buf) {
+ DynString nas = NaS;
+ /* Failed, go to NaS state */
+ free(s->s);
+ *s = nas;
+ } else {
+ s->s = buf;
+ s->b_size = (size_t)(size | STR_FREEABLE);
+ }
+}
+
+/**
+* Free the previously allocated string.
+*
+* \param s IN OUT the dynamic string
+*/
+
+void DynStringFree(DynString *s)
+{
+ DynString nas = NaS;
+
+ if (s->b_size & STR_FREEABLE) {
+ free(s->s);
+ }
+
+ *s = nas;
+}
+
+/**
+* Create a newly allocated copy of the passed dynamic string.
+*
+* \param s IN the dynamic string
+* \return the newly allocated dynamic string
+*/
+
+/* Create a new string as a copy of an old one */
+DynString *DynStringDupStr(DynString *s2, DynString *s)
+{
+ DynString nas = NaS;
+
+ /* Not a string? */
+ if (isnas(s)) {
+ return NULL;
+ }
+
+ DynStringMalloc(s2, s->size);
+ s2->size = s->size;
+ memcpy(s2->s, s->s, s->size);
+ return s2;
+}
+
+/**
+* Copy the memory from the source string into the dest string.
+*
+* \param dest IN the destination dynamic string
+* \param src IN the source dynamic string
+*/
+
+void DynStringCpyStr(DynString *dest, DynString *src)
+{
+ /* Are we no a string */
+ if (isnas(src)) {
+ return;
+ }
+
+ DynStringResize(dest, src->size);
+
+ if (isnas(dest)) {
+ return;
+ }
+
+ dest->size = src->size;
+ memcpy(dest->s, src->s, src->size);
+}
+
+/**
+* Return the content of the dynamic string as a \0 terminated C string. This memory may not be freed by the
+* caller.
+*
+* \param s IN the dynamic string
+* \return the C string
+*/
+
+char *DynStringToCStr(DynString *s)
+{
+ size_t bsize;
+
+ /* Are we not a string? */
+ if (isnas(s)) {
+ return NULL;
+ }
+
+ /* Get real buffer size */
+ bsize = s->b_size & ~STR_FREEABLE;
+
+ if (s->size == bsize) {
+ /* Increase buffer size */
+ DynStringResize(s, bsize + 1);
+
+ /* Are we no longer a string? */
+ if (isnas(s)) {
+ return NULL;
+ }
+ }
+
+ /* Tack a zero on the end */
+ s->s[s->size] = 0;
+ /* Don't update the size */
+ /* Can use this buffer as long as you don't append anything else */
+ return s->s;
+}
+
+/**
+* Concatenate a number of bytes from the source string to the dynamic string.
+*
+* \param s IN the dynamic string
+* \param len IN the number of bytes to append to the dynamic string
+* \param str IN the source string
+*/
+
+void DynStringNCatCStr(DynString *s, size_t len, const char *str)
+{
+ size_t bsize;
+
+ /* Are we not a string? */
+ if (isnas(s)) {
+ return;
+ }
+
+ /* Nothing to do? */
+ if (!str || !len) {
+ return;
+ }
+
+ /* Get real buffer size */
+ bsize = s->b_size & ~STR_FREEABLE;
+
+ if (s->size + len >= bsize) {
+ DynStringResize(s, s->size + len);
+
+ /* Are we no longer a string? */
+ if (isnas(s)) {
+ return;
+ }
+ }
+
+ memcpy(&s->s[s->size], str, len);
+ s->size += len;
+}
+
+/**
+* Concatenate a zero-terminated source string to the dynamic string.
+*
+* \param s IN the dynamic string
+* \param str IN the source string
+*/
+
+void DynStringCatCStr(DynString *s, const char *str)
+{
+ if (str) {
+ DynStringNCatCStr(s, strlen(str), str);
+ }
+}
+
+/**
+* Concatenate a dynamic string to another dynamic string.
+*
+* \param s IN the destination dynamic string
+* \param s2 IN the source dynamic string
+*/
+
+void DynStringCatStr(DynString *s, const DynString *s2)
+{
+ DynStringNCatCStr(s, s2->size, s2->s);
+}
+
+/**
+* Concatenate a variable number zero terminated strings to the dynamic string. The
+* list of source strings has to be terminated by a NULL pointer.
+*
+* \param s IN the dynamic string
+* \param ... IN variable number of C strings
+*/
+
+void DynStringCatCStrs(DynString *s, ...)
+{
+ const char *str;
+ va_list v;
+
+ /* Are we not a string? */
+ if (isnas(s)) {
+ return;
+ }
+
+ va_start(v, s);
+
+ for (str = va_arg(v, const char *); str; str = va_arg(v, const char *)) {
+ DynStringNCatCStr(s, strlen(str), str);
+ }
+
+ va_end(v);
+}
+
+/**
+* Concatenate a variable number of dynamic string to another dynamic string.
+* The list of source strings has to be terminated by a NULL pointer.
+*
+* \param s IN the destination dynamic string
+* \param s2 IN the source dynamic strings
+*/
+
+void DynStringCatStrs(DynString *s1, ...)
+{
+ const DynString *s2;
+ va_list v;
+
+ /* Are we not a string? */
+ if (isnas(s1)) {
+ return;
+ }
+
+ va_start(v, s1);
+
+ for (s2 = va_arg(v, const DynString *); s2; s2 = va_arg(v, const DynString *)) {
+ DynStringNCatCStr(s1, s2->size, s2->s);
+ }
+
+ va_end(v);
+}
+
+/**
+* Return a formatted dynamic string. Formatting is performed similar to the printf style
+* of functions.
+*
+* \param s IN the dynamic string
+* \param fmt IN format specification
+* \param ... IN values
+*/
+
+void DynStringPrintf(DynString *s, const char *fmt, ...)
+{
+ va_list v;
+ size_t len;
+ DynString nas = NaS;
+
+ ///* Are we not a string? */
+ //if (isnas(s)) {
+ // *s = STRINIT();
+ //}
+
+ /* Nothing to do? */
+ if (!fmt) {
+ return;
+ }
+
+ va_start(v, fmt);
+ len = vsnprintf(NULL, 0, fmt, v) + 1;
+ va_end(v);
+ DynStringResize(s, len);
+
+ /* Are we no longer a string? */
+ if (isnas(s)) {
+ return;
+ }
+
+ va_start(v, fmt);
+ vsnprintf(s->s, len, fmt, v);
+ va_end(v);
+ s->size = len - 1;
+}
diff --git a/app/dynstring/dynstring.h b/app/dynstring/dynstring.h
new file mode 100644
index 0000000..d6fac51
--- /dev/null
+++ b/app/dynstring/dynstring.h
@@ -0,0 +1,40 @@
+#ifndef HAVE_DYNSTRING_H
+#define HAVE_DYNSTRING_H
+
+typedef struct DynString DynString;
+struct DynString
+{
+ char *s;
+ size_t size; // length of the string
+ size_t b_size; // length of the buffer containing the string
+};
+
+#define NaS {NULL, 0, 0}
+#define isnas(S) (!(S)->s)
+
+// define highest bit depending on 32 or 64 bit compile
+
+#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
+ #define STR_FREEABLE (1ULL << 63)
+#else
+ #define STR_FREEABLE (1ULL << 31)
+#endif
+
+size_t DynStringSize(DynString * s);
+
+DynString * DynStringMalloc(DynString *s, size_t size);
+void DynStringClear(DynString *s);
+void DynStringRealloc(DynString * s);
+void DynStringResize(DynString * s, size_t size);
+void DynStringFree(DynString * s);
+DynString * DynStringDupStr(DynString *s2, DynString * s);
+void DynStringCpyStr(DynString * dest, DynString * src);
+char * DynStringToCStr(DynString * s);
+void DynStringNCatCStr(DynString * s, size_t len, const char * str);
+void DynStringCatCStr(DynString * s, const char * str);
+void DynStringCatStr(DynString * s, const DynString * s2);
+void DynStringCatCStrs(DynString * s, ...);
+void DynStringCatStrs(DynString * s1, ...);
+void DynStringPrintf(DynString * s, const char * fmt, ...);
+
+#endif // !HAVE_DYNSTRING_H
diff --git a/app/dynstring/unittest/CMakeLists.txt b/app/dynstring/unittest/CMakeLists.txt
new file mode 100644
index 0000000..7aad7c1
--- /dev/null
+++ b/app/dynstring/unittest/CMakeLists.txt
@@ -0,0 +1,8 @@
+# build unit tests for the dynstring library
+
+add_executable(dynstringtest DynStringTest.c)
+target_link_libraries(dynstringtest
+ dynstring
+ ${LIBS})
+
+add_test(DynStringTest dynstringtest) \ No newline at end of file
diff --git a/app/dynstring/unittest/DynStringTest.c b/app/dynstring/unittest/DynStringTest.c
new file mode 100644
index 0000000..33d4c9a
--- /dev/null
+++ b/app/dynstring/unittest/DynStringTest.c
@@ -0,0 +1,108 @@
+/** \file DynStringTest.c
+* Unit tests for the dynstring library
+*/
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "../dynstring.h"
+
+#define TEXT1 "Pastry gummi bears candy canes jelly beans macaroon choc"
+#define TEXT2 "olate jelly beans. Marshmallow cupcake tart jelly apple pie sesame snaps ju"
+#define TEXT3 "jubes. Tootsie roll dessert gummi bears jelly."
+
+static void PrintfString(void **state)
+{
+ DynString string;
+
+ (void)state;
+ DynStringMalloc(&string, 0);
+ DynStringPrintf(&string, "%d", 1);
+ assert_string_equal(DynStringToCStr(&string), "1");
+ DynStringFree(&string);
+}
+
+static void CopyString(void **state)
+{
+ DynString string;
+ DynString string2;
+ (void)state;
+ DynStringMalloc(&string, 0);
+ DynStringCatCStr(&string, TEXT1);
+ DynStringDupStr(&string2, &string);
+ assert_int_equal(DynStringSize(&string2), strlen(TEXT1));
+ assert_string_equal(DynStringToCStr(&string2), TEXT1);
+ DynStringFree(&string2);
+ DynStringMalloc(&string2, 0);
+ DynStringCatCStr(&string2, TEXT2);
+ DynStringCatStr(&string, &string2);
+ assert_int_equal(DynStringSize(&string), strlen(TEXT1) + strlen(TEXT2));
+ assert_string_equal(DynStringToCStr(&string), TEXT1 TEXT2);
+}
+
+static void VarStringCount(void **state)
+{
+ DynString string;
+ (void)state;
+ DynStringMalloc(&string, 0);
+ DynStringCatCStrs(&string, TEXT1, TEXT2, TEXT3, NULL);
+ assert_int_equal(DynStringSize(&string),
+ strlen(TEXT1) + strlen(TEXT2) + strlen(TEXT3));
+ assert_string_equal(DynStringToCStr(&string), TEXT1 TEXT2 TEXT3);
+ DynStringFree(&string);
+}
+
+static void MultipleStrings(void **state)
+{
+ DynString string;
+ (void)state;
+ DynStringMalloc(&string, 0);
+ DynStringCatCStr(&string, TEXT1);
+ DynStringCatCStr(&string, TEXT2);
+ assert_int_equal(DynStringSize(&string), strlen(TEXT1)+strlen(TEXT2));
+ assert_string_equal(DynStringToCStr(&string), TEXT1 TEXT2);
+ DynStringFree(&string);
+}
+
+static void SingleString(void **state)
+{
+ DynString string;
+ (void)state;
+ DynStringMalloc(&string, 0);
+ DynStringCatCStr(&string, TEXT1);
+ assert_int_equal(DynStringSize(&string), strlen(TEXT1));
+ assert_string_equal(DynStringToCStr(&string), TEXT1);
+
+ DynStringClear(&string);
+ assert_int_equal(DynStringSize(&string), 0);
+
+ DynStringFree(&string);
+}
+
+static void SimpleInitialization(void **state)
+{
+ DynString string;
+ (void)state;
+ DynStringMalloc(&string, 0);
+ assert_non_null((void *)&string);
+ assert_false(isnas(&string));
+ assert_int_equal(DynStringSize(&string), 0);
+ DynStringFree(&string);
+}
+
+int main(void)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(SimpleInitialization),
+ cmocka_unit_test(SingleString),
+ cmocka_unit_test(MultipleStrings),
+ cmocka_unit_test(VarStringCount),
+ cmocka_unit_test(CopyString),
+ cmocka_unit_test(PrintfString)
+ };
+ return cmocka_run_group_tests(tests, NULL, NULL);
+} \ No newline at end of file
diff --git a/app/help/genhelp.in b/app/help/genhelp.in
index b15a727..d4265b7 100644
--- a/app/help/genhelp.in
+++ b/app/help/genhelp.in
@@ -6,10 +6,7 @@ cmdAbout About box dialog
cmdAbove Move Selected object to top
cmdAddElevations Raise or Lower all Selected tracks
cmdBelow Move Selected object to bottom
-cmdBlockCreate Create Block
-cmdBlockDelete Delete Block
-cmdBlockEdit Edit Block
-cmdBlockSetCmd Block
+cmdBlockCreate Create a section of track for automation.
cmdCarDesc Create a new Car/Loco description
cmdCarInventory Manage your Car and Loco Inventory
cmdCircleCenter Create track circle from center cmdCircle
@@ -21,6 +18,7 @@ cmdClearElevations Removes elevation from Selected tracks
cmdCmdopt Command Options dialog
cmdColor Controls colors
cmdConnect Connect two tracks
+cmdControl Create a control for layout automation
cmdCopy Copy selected objects to clipboard
cmdCurveCenter Create curved track from center cmdCurve
cmdCurveChord Create curved track from chord cmdCurve
@@ -126,13 +124,12 @@ cmdSelectCurrentLayer Selects all objects in the current Layer layer
cmdSelectInvert Invert current selection
cmdSplitTrack Split a track
cmdSelectOrphaned Select stranded (unconnected) track pieces
+cmdSensor Create a sensor (ie. a occupancy detector or a toggle switch)
+cmdSignal Create a signal for train control
cmdSticky Choose which commands are sticky
cmdStraight Create straight track
cmdStructure Place a structure on the layout
-cmdSwitchMotorCreate Create Switch Motor
-cmdSwitchMotorDelete Delete Switch Motor
-cmdSwitchMotorEdit Edit Switch Motor
-cmdSwitchMotorSetCmd Switch Motors
+cmdSwitchMotorCreate Create a switchmotor for turnout control
cmdText Enter text on the layout
cmdTextSize Controls the size of the entered text cmdText
#cmdTighten Remove slack from connected tracks
@@ -346,7 +343,7 @@ draw-benchorient Orientation of Benchwork cmdDraw
draw-arrowsize Size of Dimension Arrows cmdDraw
#
easement-val This controls the sharpness of the easement curve cmdEasement
-easement-r Minumum radius cmdEasement
+easement-r Minimum radius cmdEasement
easement-x Maximum offset cmdEasement
easement-l Easement length cmdEasement
easement-radio These radio buttons are a short-cut for Values of 0.0, 0.5, 1.0 and 2.0. None turns Easements off cmdEasement
diff --git a/app/help/xtrkcad.info b/app/help/xtrkcad.info
index 39c343e..955bab7 100644
--- a/app/help/xtrkcad.info
+++ b/app/help/xtrkcad.info
@@ -1,3 +1,8 @@
+INFO-DIR-SECTION CAD
+START-INFO-DIR-ENTRY
+* xtrkcad: xtrkcad-4.2.4. Model Train Track CAD Program
+END-INFO-DIR-ENTRY
+
:Help
Invokes on-line help for this dialog
:cancel
@@ -12,6 +17,8 @@ Move Selected object to top
Raise or Lower all Selected tracks
:cmdBelow
Move Selected object to bottom
+:cmdBlockCreate
+Create a section of track for automation.
:cmdCarDesc
Create a new Car/Loco description
:cmdCarInventory
@@ -34,6 +41,8 @@ Controls colors
Connect two tracks
:cmdCopy
Copy selected objects to clipboard
+:cmdControl
+Create a control for layout automation
:cmdCurveCenter
Create curved track from center
:cmdCurveChord
@@ -194,16 +203,22 @@ Selects all objects on the layout
Selects all objects in the current Layer
:cmdSelectInvert
Invert current selection
+:cmdSensor
+Create a sensor (ie. a occupancy detector or a toggle switch)
:cmdSplitTrack
Split a track
:cmdSelectOrphaned
Select stranded (unconnected) track pieces
+:cmdSignal
+Create a signal for train control
:cmdSticky
Choose which commands are sticky
:cmdStraight
Create straight track
:cmdStructure
Place a structure on the layout
+:cmdSwitchMotorCreate
+Create a switchmotor for turnout control
:cmdText
Enter text on the layout
:cmdTextSize
@@ -1099,3 +1114,4 @@ Layer
:cmdLayerShow19
Layer
:
+
diff --git a/app/i18n/de_DE.po b/app/i18n/de_DE.po
index a97c2a0..7f03e3a 100644
--- a/app/i18n/de_DE.po
+++ b/app/i18n/de_DE.po
@@ -3,14 +3,14 @@ msgstr ""
"Project-Id-Version: xtrkcad 4.1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-06 12:30+0100\n"
-"PO-Revision-Date: 2016-02-06 12:35+0100\n"
+"PO-Revision-Date: 2016-08-25 10:38+0200\n"
"Last-Translator: \n"
"Language-Team: German <m_fischer@users.sourceforge.net>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 1.8.1\n"
+"X-Generator: Poedit 1.8.4\n"
#: ../bin/cblock.c:98 ../bin/cblock.c:133 ../bin/compound.c:520
#: ../bin/cswitchmotor.c:78 ../bin/cswitchmotor.c:138 ../bin/dlayer.c:319
@@ -59,40 +59,40 @@ msgid "Block"
msgstr "Block"
#: ../bin/cblock.c:442 ../bin/cblock.c:461 ../bin/cblock.c:469
-#: ../bin/cblock.c:525 ../bin/cdraw.c:78 ../bin/cdraw.c:870
-#: ../bin/cgroup.c:962 ../bin/cgroup.c:1009 ../bin/cgroup.c:1024
-#: ../bin/cgroup.c:1063 ../bin/cgroup.c:1089 ../bin/cgroup.c:1148
-#: ../bin/cgroup.c:1592 ../bin/cnote.c:96 ../bin/cprint.c:520
-#: ../bin/cprint.c:945 ../bin/cpull.c:499 ../bin/cpull.c:514
-#: ../bin/cpull.c:516 ../bin/cpull.c:518 ../bin/cselect.c:670
-#: ../bin/cselect.c:767 ../bin/cselect.c:1243 ../bin/csnap.c:578
-#: ../bin/csnap.c:711 ../bin/cstruct.c:763 ../bin/cstruct.c:772
-#: ../bin/cstruct.c:874 ../bin/cswitchmotor.c:355 ../bin/cswitchmotor.c:381
-#: ../bin/ctext.c:163 ../bin/ctodesgn.c:150 ../bin/ctodesgn.c:1040
-#: ../bin/ctodesgn.c:1090 ../bin/ctodesgn.c:1203 ../bin/ctodesgn.c:1505
-#: ../bin/ctrain.c:2561 ../bin/cturnout.c:2381 ../bin/cturnout.c:2508
-#: ../bin/cundo.c:152 ../bin/cundo.c:156 ../bin/dbitmap.c:65
-#: ../bin/dbitmap.c:122 ../bin/dbitmap.c:200 ../bin/dbitmap.c:235
-#: ../bin/dcar.c:3528 ../bin/dcar.c:3712 ../bin/dcar.c:3716 ../bin/dcar.c:3720
-#: ../bin/dcar.c:3725 ../bin/dcar.c:4039 ../bin/dcar.c:4150 ../bin/dcar.c:4528
-#: ../bin/dcmpnd.c:387 ../bin/dcmpnd.c:398 ../bin/dcmpnd.c:530
-#: ../bin/dcustmgm.c:186 ../bin/dcustmgm.c:192 ../bin/dcustmgm.c:201
-#: ../bin/dcustmgm.c:217 ../bin/dease.c:220 ../bin/dlayer.c:200
-#: ../bin/dlayer.c:217 ../bin/dlayer.c:657 ../bin/dlayer.c:662
-#: ../bin/doption.c:155 ../bin/doption.c:274 ../bin/doption.c:354
-#: ../bin/doption.c:505 ../bin/doption.c:517 ../bin/doption.c:583
-#: ../bin/dprmfile.c:91 ../bin/dprmfile.c:105 ../bin/dprmfile.c:118
-#: ../bin/dprmfile.c:160 ../bin/dprmfile.c:438 ../bin/draw.c:2234
-#: ../bin/fileio.c:609 ../bin/fileio.c:678 ../bin/fileio.c:789
-#: ../bin/fileio.c:791 ../bin/fileio.c:796 ../bin/fileio.c:958
-#: ../bin/macro.c:934 ../bin/macro.c:938 ../bin/macro.c:1015
-#: ../bin/macro.c:1121 ../bin/macro.c:1349 ../bin/macro.c:1365
-#: ../bin/misc2.c:411 ../bin/param.c:1820 ../bin/param.c:1944
-#: ../bin/param.c:1947 ../bin/param.c:2069 ../bin/param.c:2075
-#: ../bin/smalldlg.c:91 ../bin/smalldlg.c:221 ../bin/tease.c:1039
-#: ../bin/track.c:1311 ../bin/misc.c:304 ../bin/misc.c:354 ../bin/misc.c:1712
-#: ../bin/misc.c:1846 ../bin/misc.c:1910 ../bin/misc.c:2476 ../bin/misc.c:2486
-#: ../bin/misc.c:2506 ../bin/misc.c:2509 ../wlib/gtklib/wpref.c:126
+#: ../bin/cblock.c:525 ../bin/cdraw.c:78 ../bin/cdraw.c:870 ../bin/cgroup.c:962
+#: ../bin/cgroup.c:1009 ../bin/cgroup.c:1024 ../bin/cgroup.c:1063
+#: ../bin/cgroup.c:1089 ../bin/cgroup.c:1148 ../bin/cgroup.c:1592
+#: ../bin/cnote.c:96 ../bin/cprint.c:520 ../bin/cprint.c:945 ../bin/cpull.c:499
+#: ../bin/cpull.c:514 ../bin/cpull.c:516 ../bin/cpull.c:518
+#: ../bin/cselect.c:670 ../bin/cselect.c:767 ../bin/cselect.c:1243
+#: ../bin/csnap.c:578 ../bin/csnap.c:711 ../bin/cstruct.c:763
+#: ../bin/cstruct.c:772 ../bin/cstruct.c:874 ../bin/cswitchmotor.c:355
+#: ../bin/cswitchmotor.c:381 ../bin/ctext.c:163 ../bin/ctodesgn.c:150
+#: ../bin/ctodesgn.c:1040 ../bin/ctodesgn.c:1090 ../bin/ctodesgn.c:1203
+#: ../bin/ctodesgn.c:1505 ../bin/ctrain.c:2561 ../bin/cturnout.c:2381
+#: ../bin/cturnout.c:2508 ../bin/cundo.c:152 ../bin/cundo.c:156
+#: ../bin/dbitmap.c:65 ../bin/dbitmap.c:122 ../bin/dbitmap.c:200
+#: ../bin/dbitmap.c:235 ../bin/dcar.c:3528 ../bin/dcar.c:3712
+#: ../bin/dcar.c:3716 ../bin/dcar.c:3720 ../bin/dcar.c:3725 ../bin/dcar.c:4039
+#: ../bin/dcar.c:4150 ../bin/dcar.c:4528 ../bin/dcmpnd.c:387
+#: ../bin/dcmpnd.c:398 ../bin/dcmpnd.c:530 ../bin/dcustmgm.c:186
+#: ../bin/dcustmgm.c:192 ../bin/dcustmgm.c:201 ../bin/dcustmgm.c:217
+#: ../bin/dease.c:220 ../bin/dlayer.c:200 ../bin/dlayer.c:217
+#: ../bin/dlayer.c:657 ../bin/dlayer.c:662 ../bin/doption.c:155
+#: ../bin/doption.c:274 ../bin/doption.c:354 ../bin/doption.c:505
+#: ../bin/doption.c:517 ../bin/doption.c:583 ../bin/dprmfile.c:91
+#: ../bin/dprmfile.c:105 ../bin/dprmfile.c:118 ../bin/dprmfile.c:160
+#: ../bin/dprmfile.c:438 ../bin/draw.c:2234 ../bin/fileio.c:609
+#: ../bin/fileio.c:678 ../bin/fileio.c:789 ../bin/fileio.c:791
+#: ../bin/fileio.c:796 ../bin/fileio.c:958 ../bin/macro.c:934
+#: ../bin/macro.c:938 ../bin/macro.c:1015 ../bin/macro.c:1121
+#: ../bin/macro.c:1349 ../bin/macro.c:1365 ../bin/misc2.c:411
+#: ../bin/param.c:1820 ../bin/param.c:1944 ../bin/param.c:1947
+#: ../bin/param.c:2069 ../bin/param.c:2075 ../bin/smalldlg.c:91
+#: ../bin/smalldlg.c:221 ../bin/tease.c:1039 ../bin/track.c:1311
+#: ../bin/misc.c:304 ../bin/misc.c:354 ../bin/misc.c:1712 ../bin/misc.c:1846
+#: ../bin/misc.c:1910 ../bin/misc.c:2476 ../bin/misc.c:2486 ../bin/misc.c:2506
+#: ../bin/misc.c:2509 ../wlib/gtklib/wpref.c:126
#: ../../../build/xtc_4-2-3dev/app/bin/bllnhlp.c:523
msgid "Ok"
msgstr "Ok"
@@ -142,8 +142,7 @@ msgstr "Ja"
#: ../bin/ctrain.c:2056 ../bin/dcar.c:3664 ../bin/dcar.c:3742
#: ../bin/dcar.c:3826 ../bin/dcar.c:3845 ../bin/dcar.c:4175 ../bin/dcar.c:4590
#: ../bin/dcustmgm.c:136 ../bin/track.c:1313 ../bin/track.c:1410
-#: ../bin/track.c:1424 ../bin/misc.c:1053 ../bin/misc.c:1058
-#: ../bin/misc.c:1123
+#: ../bin/track.c:1424 ../bin/misc.c:1053 ../bin/misc.c:1058 ../bin/misc.c:1123
msgid "No"
msgstr "Nein"
@@ -154,11 +153,11 @@ msgstr "Gleisabschnitt löschen"
#: ../bin/cblock.c:641
msgid "Blocks"
-msgstr "Blocks"
+msgstr "Gleisabschnitte"
#: ../bin/cblock.c:643 ../../../build/xtc_4-2-3dev/app/bin/bllnhlp.c:19
msgid "Edit Block"
-msgstr "Block bearbeiten"
+msgstr "Gleisabschnitt bearbeiten"
#: ../bin/ccurve.c:102
msgid "Drag from End-Point in direction of curve"
@@ -178,7 +177,7 @@ msgstr "Zum anderen Ende der Sehne ziehen"
#: ../bin/ccurve.c:128 ../bin/chndldto.c:91
msgid "Drag to set angle"
-msgstr "Ziehen um den Winkel zu ändern"
+msgstr "Durch Ziehen den Winkel festlegen"
#: ../bin/ccurve.c:156
#, c-format
@@ -264,7 +263,7 @@ msgstr "Gleiswendel"
#: ../bin/ccurve.c:524
msgid "Circle Radius"
-msgstr "Radius des Kreis"
+msgstr "Kreisradius"
#: ../bin/ccurve.c:529
msgid "Click on Circle Edge"
@@ -272,7 +271,7 @@ msgstr "Auf den Rand des Kreis klicken"
#: ../bin/ccurve.c:533
msgid "Click on Circle Center"
-msgstr "Auf Kreismittelpunkt klicken"
+msgstr "Auf den Mittelpunkt des Kreises klicken"
#: ../bin/ccurve.c:564
msgid "Drag to Center"
@@ -280,7 +279,7 @@ msgstr "Zum Mittelpunkt ziehen"
#: ../bin/ccurve.c:568
msgid "Drag to Edge"
-msgstr "Zur Kante ziehen"
+msgstr "Zum Rand ziehen"
#: ../bin/ccurve.c:589 ../bin/ccurve.c:593
#, c-format
@@ -305,7 +304,7 @@ msgstr "Radius durch Ziehen festlegen"
#: ../bin/ccurve.c:686
msgid "Place circle"
-msgstr "Setze Kreis"
+msgstr "Platziere Kreis"
#: ../bin/ccurve.c:711
msgid "Curve Track"
@@ -313,19 +312,19 @@ msgstr "Gleisbogen"
#: ../bin/ccurve.c:711
msgid "Curve Tracks"
-msgstr "Gleise biegen"
+msgstr "Gleisbögen"
#: ../bin/ccurve.c:712
msgid "Curve from End-Pt"
-msgstr "Bogen aus Endpunkte"
+msgstr "Bogen aus Endpunkten"
#: ../bin/ccurve.c:713
msgid "Curve from Tangent"
-msgstr "Bogen aus Tangente"
+msgstr "Bogen an Tangente"
#: ../bin/ccurve.c:714
msgid "Curve from Center"
-msgstr "Bogen aus Mittelpunkt"
+msgstr "Bogen um Mittelpunkt"
#: ../bin/ccurve.c:715
msgid "Curve from Chord"
@@ -345,11 +344,11 @@ msgstr "Kreis mit festem Radius"
#: ../bin/ccurve.c:720
msgid "Circle from Tangent"
-msgstr "Kreis aus Tangente"
+msgstr "Kreis an Tangente"
#: ../bin/ccurve.c:721
msgid "Circle from Center"
-msgstr "Kreis aus Mittelpunkt"
+msgstr "Kreis um Mittelpunkt"
#: ../bin/cdraw.c:78
msgid "Font Size must be > 0"
@@ -371,15 +370,15 @@ msgstr "Winkel"
#: ../bin/cdraw.c:196 ../bin/tcurve.c:352
msgid "CCW Angle"
-msgstr "Winkel (gegen Uhrzeiger)"
+msgstr "Winkel (gegen Uhrzeigersinn)"
#: ../bin/cdraw.c:197 ../bin/tcurve.c:353
msgid "CW Angle"
-msgstr "Winkel (im Uhrzeiger)"
+msgstr "Winkel (im Uhrzeigersinn)"
#: ../bin/cdraw.c:198
msgid "Point Count"
-msgstr "Anzahl Punkte"
+msgstr "Anzahl der Punkte"
#: ../bin/cdraw.c:199 ../bin/cdraw.c:811 ../bin/ctodesgn.c:148
msgid "Line Width"
@@ -418,8 +417,8 @@ msgstr "Schriftgröße"
msgid "Text"
msgstr "Text"
-#: ../bin/cdraw.c:208 ../bin/cmisc.c:114 ../bin/tcurve.c:355
-#: ../bin/tease.c:509 ../bin/tstraigh.c:84
+#: ../bin/cdraw.c:208 ../bin/cmisc.c:114 ../bin/tcurve.c:355 ../bin/tease.c:509
+#: ../bin/tstraigh.c:84
msgid "Pivot"
msgstr "Drehpunkt"
@@ -454,7 +453,7 @@ msgstr "Gerade Linie"
#: ../bin/cdraw.c:421 ../bin/cdraw.c:1036
msgid "Dimension Line"
-msgstr "Maßstablinie"
+msgstr "Maßlinie"
#: ../bin/cdraw.c:436 ../bin/cdraw.c:832 ../bin/cdraw.c:1038
msgid "Table Edge"
@@ -515,7 +514,7 @@ msgstr "Gerade"
#: ../bin/cdraw.c:830
msgid "Dimension"
-msgstr "Abmessungen"
+msgstr "Abmessung"
#: ../bin/cdraw.c:833 ../bin/cdraw.c:834 ../bin/cdraw.c:835 ../bin/cdraw.c:836
msgid "Curved"
@@ -536,7 +535,7 @@ msgstr "Gefülltes Rechteck"
#: ../bin/cdraw.c:888
#, c-format
msgid "%s Line Width"
-msgstr "%s Strichstärke"
+msgstr "%s Strichdicke"
#: ../bin/cdraw.c:901
#, c-format
@@ -549,7 +548,7 @@ msgstr " Maßliniengröße"
#: ../bin/cdraw.c:945
msgid "Drag to create Table Edge"
-msgstr "Ziehen um die Tischkante zu erstellen"
+msgstr "Durch Ziehen die Tischkante erstellen"
#: ../bin/cdraw.c:1035
msgid "Line"
@@ -577,7 +576,7 @@ msgstr "Zeichne Tischkante"
#: ../bin/cdraw.c:1040
msgid "Curve End"
-msgstr "Kurve Enden "
+msgstr "Kurvenenden "
#: ../bin/cdraw.c:1040
msgid "Draw Curve from End"
@@ -593,7 +592,7 @@ msgstr "Zeichne Kurve an Tangente"
#: ../bin/cdraw.c:1042
msgid "Curve Center"
-msgstr "Kurve Mittelpunkt"
+msgstr "Kurve um Mittelpunkt"
#: ../bin/cdraw.c:1042
msgid "Draw Curve from Center"
@@ -601,15 +600,15 @@ msgstr "Zeichne Kurve um Mittelpunkt"
#: ../bin/cdraw.c:1043
msgid "Curve Chord"
-msgstr "Kurve Sehne "
+msgstr "Kurve durch Sehne "
#: ../bin/cdraw.c:1043
msgid "Draw Curve from Chord"
-msgstr "Bogen aus Sehne"
+msgstr "Zeichne Kurve durch Sehne"
#: ../bin/cdraw.c:1046
msgid "Circle Tangent"
-msgstr "Kreis Tangente"
+msgstr "Kreis an Tangente"
#: ../bin/cdraw.c:1046
msgid "Draw Circle from Tangent"
@@ -625,7 +624,7 @@ msgstr "Zeichne Kreis um Mittelpunkt"
#: ../bin/cdraw.c:1049
msgid "Circle Filled Tangent"
-msgstr "Gefüllter Kreis Tangente"
+msgstr "Gefüllter Kreis an Tangente"
#: ../bin/cdraw.c:1049
msgid "Draw Filled Circle from Tangent"
@@ -777,9 +776,8 @@ msgstr "Durch neue Gruppe ersetzen?"
#: ../bin/cgroup.c:604 ../bin/compound.c:519 ../bin/cstruct.c:64
#: ../bin/ctodesgn.c:140 ../bin/ctodesgn.c:1764 ../bin/cturnout.c:69
-#: ../bin/dcar.c:1933 ../bin/dcar.c:4070 ../bin/dcar.c:4075
-#: ../bin/dcmpnd.c:444 ../bin/dcustmgm.c:45
-#: ../../../build/xtc_4-2-3dev/app/bin/bllnhlp.c:333
+#: ../bin/dcar.c:1933 ../bin/dcar.c:4070 ../bin/dcar.c:4075 ../bin/dcmpnd.c:444
+#: ../bin/dcustmgm.c:45 ../../../build/xtc_4-2-3dev/app/bin/bllnhlp.c:333
#: ../../../build/xtc_4-2-3dev/app/bin/bllnhlp.c:502
msgid "Manufacturer"
msgstr "Hersteller"
@@ -1796,8 +1794,7 @@ msgstr "Weichendesigner"
msgid "%s %s Designer"
msgstr "%s %s Designer"
-#: ../bin/ctrain.c:168 ../bin/dcar.c:1986 ../bin/dcar.c:4070
-#: ../bin/dcar.c:4075
+#: ../bin/ctrain.c:168 ../bin/dcar.c:1986 ../bin/dcar.c:4070 ../bin/dcar.c:4075
msgid "Index"
msgstr "Verzeichnis"
@@ -2153,17 +2150,16 @@ msgstr ""
"Falscher Trägertyp %s:\n"
"%s"
-#: ../bin/dbench.c:142 ../bin/dcar.c:4225 ../bin/dcar.c:4409
-#: ../bin/dcar.c:4419 ../bin/dcar.c:4466 ../bin/dcar.c:4473 ../bin/dcar.c:4491
-#: ../bin/dcar.c:4504 ../bin/dcar.c:4509 ../bin/dcar.c:4538 ../bin/dcar.c:4699
-#: ../bin/fileio.c:242 ../bin/fileio.c:538 ../bin/fileio.c:656
-#: ../bin/fileio.c:749 ../bin/fileio.c:938 ../bin/fileio.c:1231
-#: ../bin/fileio.c:1375 ../bin/fileio.c:1461 ../bin/fileio.c:1507
-#: ../bin/macro.c:165 ../bin/macro.c:833 ../bin/macro.c:849
-#: ../bin/macro.c:1152 ../bin/param.c:2062 ../bin/track.c:931
-#: ../bin/track.c:1297 ../bin/track.c:1588 ../bin/track.c:1592
-#: ../bin/track.c:1612 ../bin/track.c:1674 ../wlib/gtklib/wpref.c:246
-#: ../wlib/gtklib/wpref.c:253
+#: ../bin/dbench.c:142 ../bin/dcar.c:4225 ../bin/dcar.c:4409 ../bin/dcar.c:4419
+#: ../bin/dcar.c:4466 ../bin/dcar.c:4473 ../bin/dcar.c:4491 ../bin/dcar.c:4504
+#: ../bin/dcar.c:4509 ../bin/dcar.c:4538 ../bin/dcar.c:4699 ../bin/fileio.c:242
+#: ../bin/fileio.c:538 ../bin/fileio.c:656 ../bin/fileio.c:749
+#: ../bin/fileio.c:938 ../bin/fileio.c:1231 ../bin/fileio.c:1375
+#: ../bin/fileio.c:1461 ../bin/fileio.c:1507 ../bin/macro.c:165
+#: ../bin/macro.c:833 ../bin/macro.c:849 ../bin/macro.c:1152
+#: ../bin/param.c:2062 ../bin/track.c:931 ../bin/track.c:1297
+#: ../bin/track.c:1588 ../bin/track.c:1592 ../bin/track.c:1612
+#: ../bin/track.c:1674 ../wlib/gtklib/wpref.c:246 ../wlib/gtklib/wpref.c:253
msgid "Continue"
msgstr "Weiter"
@@ -2454,8 +2450,7 @@ msgstr "Hinzufügen"
msgid "Update %s Scale Car"
msgstr "Aktualisiere Wagen in Maßstab %s"
-#: ../bin/dcar.c:2822 ../bin/dcar.c:2831 ../bin/dcar.c:2840
-#: ../bin/dcmpnd.c:166
+#: ../bin/dcar.c:2822 ../bin/dcar.c:2831 ../bin/dcar.c:2840 ../bin/dcmpnd.c:166
msgid "Update"
msgstr "Aktualisieren"
@@ -6814,7 +6809,7 @@ msgid "This controls the sharpness of the easement curve"
msgstr "Steuert die Größe des Übergangsradius"
#: ../../../build/xtc_4-2-3dev/app/bin/bllnhlp.c:306
-msgid "Minumum radius"
+msgid "Minimum radius"
msgstr "Mindestgleisradius"
#: ../../../build/xtc_4-2-3dev/app/bin/bllnhlp.c:307
diff --git a/app/i18n/fi.po b/app/i18n/fi.po
index 0a6ba8f..be9826e 100644
--- a/app/i18n/fi.po
+++ b/app/i18n/fi.po
@@ -5702,7 +5702,7 @@ msgid "Mint"
msgstr "Loistava"
#: ../../../../build/xtrkcad/app/bin/bllnhlp.c:298
-msgid "Minumum radius"
+msgid "Minimum radius"
msgstr "Pienin karresäde"
#: ../../../../build/xtrkcad/app/i18n/custmsg.h:41
diff --git a/app/i18n/pt_BR.po b/app/i18n/pt_BR.po
index b9c7ac0..d7304ed 100644
--- a/app/i18n/pt_BR.po
+++ b/app/i18n/pt_BR.po
@@ -7210,7 +7210,7 @@ msgid "This controls the sharpness of the easement curve"
msgstr ""
#: ../../../../xtrkcad-build/app/bin/bllnhlp.c:297
-msgid "Minumum radius"
+msgid "Minimum radius"
msgstr ""
#: ../../../../xtrkcad-build/app/bin/bllnhlp.c:298
diff --git a/app/lib/CMakeLists.txt b/app/lib/CMakeLists.txt
index 2ec9d2d..3de124e 100644
--- a/app/lib/CMakeLists.txt
+++ b/app/lib/CMakeLists.txt
@@ -15,3 +15,14 @@ INSTALL(FILES
xtrkcad.xtq
DESTINATION ${XTRKCAD_SHARE_INSTALL_DIR}
)
+
+IF(UNIX AND NOT APPLE)
+ INSTALL(FILES
+ xtrkcad.desktop
+ DESTINATION "/usr/share/applications"
+ )
+ INSTALL(FILES
+ xtrkcad.png
+ DESTINATION "/usr/share/pixmaps"
+ )
+ENDIF(UNIX AND NOT APPLE) \ No newline at end of file
diff --git a/app/lib/Readme.md b/app/lib/Readme.md
index 297fd18..dfa904d 100644
--- a/app/lib/Readme.md
+++ b/app/lib/Readme.md
@@ -1,4 +1,4 @@
-# XTrackCAD 4.2.4a #
+# XTrackCAD 4.3.0 #
This file contains installation instructions and up-to-date information regarding XTrackCad.
@@ -39,6 +39,25 @@ you can find in the file COPYING.
## New features ##
+### Version 4.3.0 ###
+
+* Linux: Install xtrkcad.desktop and xtrkcad.png for desktop integration
+* All: Fix color button initialization
+* Add control and sensor types
+* Development of signal feature was finished
+* Add extra AppleHelp files
+* All: Add documentation for layout control elements
+* Write proper Describe, Move, and Rotate functions for Signals.
+* Add high lighting for signals.
+* Add AppleHelp bundle generation including index
+* First pass at high lighting layout control elements.
+* Linux/OSX: Set directory for rc file
+* All: Rework DXF export, add support for metric measurements
+* All: Add dynstring to build and modify DynstrMalloc interface
+* All: Add dynstring library and unit tests
+* All: enable unit testing with CMocka
+* Add Layout Control Element management dialog
+
### Version 4.2.4 ###
* All: Parameter file for Minitrains HOe-009-HOn30 Track System
* All: Improved and new parameter files Kato N and Super O
@@ -94,7 +113,46 @@ you can find in the file COPYING.
* Update help CSS to the Wiki's new default look
## Bugs fixed ##
+
+### Version 4.3.0 ###
+* All: Save and set user defined values for Text command
+* All: Fix path handling error after Save/Save As
+* All: Fix color button initialization
+* Fix Malloc error (wrong size in ReadBlock, causing Guard1 hose error)
+* Updated cblock.c and cswitchmotor.c to handle possible broken blocks and switchmotors and not crash (check for NULL pointers)
+* Bulletproof against undefined (NULL pointer) track segments in SwitchMotor code.
+* Bulletproof against undefined (NULL pointer) track segments in Block code.
+* Linux/OSX: Preparing for GTK3 migration, second set of changes
+* Clean up help files for Apple Help Indexer
+* Linux/OSX: Preparing for GTK3 migration, first set of changes
+* All: New and updated parameter files for Lego and Peco H0 Code 83
+* Linux/OSX: Add OSX specific files
+* Linux/OSX: Split help functions in generic and platform specific piece
+* Description: Correct some translation typos
+* Linux/OSX: Fix #163 GCC format-security errors
+* All: Update parameter file for Kuehn TT track
+* Add forward reference resolution for Blocks and Switchmotors
+* Cleanly delete blocks and switch motors when their tracks are deleted (avoid dangling pointers)
+* Updated Spec file
+* Expand help path name for longer bundle directories
+* Attempt to fix help files crash issue
+* Add GLIB Schemas to GTK-Bundle
+* All: Improved German translations
+* Update Readme for OSX package
+* Add support for gtk-mac-bundler
+* fix bugs in xtrkcad-bundler code
+* Fix parm dialog default for GTK builds
+* Add a post-build script for auto-creating OSX images
+* Remove failing copy command for gtk-bundle share
+* Linux/OSX: Fix uninitialized param file directory on first run
+* All: Add TTi scale / gauge
+* All: New paramter files for Frateschi HO and Auhagen TTi
+
### Version 4.2.4a ###
+* All: Update help
+* Linux: Installation from self extracting archive accepts install path
+* Linux/OSX: Remove absolute path from source packages
+* All: remove all dependencies on obsolete XTRKCAD_USE_LAYOUTCONTROL conditional
* All: New parameter file for Micro Engineering HOn3 Turnouts
* Windows: Fix bug 157 Crash on color change when drawing lines
* All: Updated parameter file for Kato N scale
@@ -242,19 +300,19 @@ self-installing program using the NSIS Installer from Nullsoft Inc.
Using Windows Explorer, locate the directory in which you downloaded or copied your new version of XTrackCAD.
Start the installation program by double clicking on the
-**[xtrkcad-setup-4.2.4.exe][]** file icon.
+**[xtrkcad-setup-4.3.0.exe][]** file icon.
Follow the steps in the installation program.
The installation lets you define the directory into which XTrackCAD is
installed. The directory is created automatically if it doesn't already exist.
-A program folder named XTrackCAD 4.2.4 will be created during the installation
+A program folder named XTrackCAD 4.3.0 will be created during the installation
process. This folder contains the program, documentation, parameter and
example files. An existing installation of earlier versions of XTrackCad is
not overwritten.
-A new program group named XTrackCad 4.2.4 will be created in the Start menu.
+A new program group named XTrackCad 4.3.0 will be created in the Start menu.
## Linux ##
@@ -269,7 +327,7 @@ Use your operating system's package manager to install XTrackCAD.
After downloading open a command line then
- ./xtrkcad-setup-4.2.4.x86_64.sh --prefix=/usr/local --exclude-subdir
+ ./xtrkcad-setup-4.3.0.x86_64.sh --prefix=/usr/local --exclude-subdir
This will install the executable in /usr/local/bin. A directory named
xtrkcad will be created in /usr/local/share and all files will be unpacked
diff --git a/app/lib/Readme.txt b/app/lib/Readme.txt
index e98f6d6..568b2e5 100644
--- a/app/lib/Readme.txt
+++ b/app/lib/Readme.txt
@@ -1,492 +1,559 @@
-
-
-XTRACKCAD 4.2.4A
-
-
-This file contains installation instructions and up-to-date information
-regarding XTrackCad.
-
-
-Contents
-
-- About XTrackCad
-- License Information
-- New features in this release
-- Installation
-- Upgrading from earlier releases
-- Bugs fixed
-- Building
-- Where to go for support
-
-
-About XTrackCad
-
-XTrackCad is a powerful CAD program for designing Model Railroad
-layouts.
-
-Some highlights:
-
-- Easy to use.
-- Supports any scale.
-- Supplied with parameter libraries for many popular brands of
- turnouts, plus the capability to define your own.
-- Automatic easement (spiral transition) curve calculation.
-- Extensive help files and video-clip demonstration mode.
-
-Availability: XTrkCad Fork is a project for further development of the
-original XTrkCad software. See the project homepage at
-http://www.xtrackcad.org/ for news and current releases.
-
-
-License Information
-
-COPYING:
-
-XTrackCad is copyrighted by Dave Bullis and Martin Fischer and licensed
-as free software under the terms of the GNU General Public License v2
-which you can find in the file COPYING.
-
-
-New features
-
-Version 4.2.4
-
-- All: Parameter file for Minitrains HOe-009-HOn30 Track System
-- All: Improved and new parameter files Kato N and Super O
-- All: Corrected parameter file for Peco HOn30/OO9 track
-- All: New parameter file for Peco HOn3 turnouts
-- All: New and updated parameter files for Z-scale
-- All: added a few more length formats
-- All: added additional zoom and marco zoom steps
-- All: Increase meximum number of layer buttons to 99
-- All: The parameter file dialog now allows loading and unloading
- several files together
-
-Version 4.2.3
-
-- All: updated German translations
-- All: TT Kuehn added items
-- Linux/OSX: New printing system
-- All: tomix-n.xtp Added or Updated multiple items
-- All: Add length format with six decimal places for English units
- (feature wish #33)
-- All: Feature Request #35: add hotkey for switching map window on and
- off
-- All: Make the installation's param directory the default on initial
- run
-- All: several new and updated parameter files
-- All: add Nm gauge and some Nm track parameters
-
-Version 4.2.2
-
-- All: Update German translations
-- All: extended parameter files f𲠋ato HO and Walthers N structures
-- All: Added and extended parameter files
-- All: Add support for HOf scale/gauge and Busch track parameter files
-- Linux/OSX: Replace file selector dialog with newer file chooser
- dialog
-- All: Make editing of custom track work
-- All: Fix Atlas HO Code 100 parameter file
-- All: new Kato Unitrack N-Scale parameter file
-- All: add measurement units to train speed
-
-Version 4.2.1
-
-- Increase the number of layer buttons to 99
-- All: Update Eishindo T Gauge parameter file
-- All: Paste clipboard content at position of mouse pointer
-- All: Never mark curve centers of turnouts
-- All: Make drawing of center markings (crosshair) an user option
-- add ability to set text color when creating them
-- Windows: Draw and print crosshair to mark the center of an arc
-- Add the ability to change layers of a piece of track in the
- describe box.
-
-Version 4.2.0
-
-- New and updated parameter files and layout examples
-- Apply user preferences for dimensions to elevations
-- Add ability to update color of Text in properties
-- Fix compile problem on FreeBSD
-- Fix Oracle Solaris Studio 12.3 warnings
-- partially completed Brazilian Portuguese translation (57%)
-- Improve German translations
-- Merged webkit help system from Debian
-- Update help CSS to the Wiki's new default look
-
-
-Bugs fixed
-
-Version 4.2.4a
-
-- All: New parameter file for Micro Engineering HOn3 Turnouts
-- Windows: Fix bug 157 Crash on color change when drawing lines
-- All: Updated parameter file for Kato N scale
-- All: Fix build problem with block and switchmotor feature
-
-Version 4.2.4
-
-- Linux/OSX: Correct search order for config files
-- All: Layout control functions are always included
-- Linux/OSX: add a default file extension when none is present on save
-- Linux/OSX: Update package build
-- All: Fix compiler warnings for pointer to in casts on 64 bit systems
-- All: Correct file comments
-- All: Consistent spelling
-- All: Fix definition for Atlas Code 83 3/4" straight track
-
-Version 4.2.3b
-
-- Windows: Fix numeric overflow when reading layouts created on Linux
-- Linux/OSX: Fix crash when closing Train Control window
-- Linux/OSX: Fix crash when closing Change Elevation Window
-- All: new and improved parameter files for Tillig track
-
-Version 4.2.3a
-
-- Windows: Make UI translation work with directory structure of 64 bit
- Windows
-- Linux/OSX: Use defaults for printer and page settings on first run
-
-Version 4.2.3
-
-- All: Fix bug #143: Roco N Turnout 22247
-- All: fix invalid const variable usage
-- Linux/OSX: cairo is required and no longer optional
-- All: Fix bug #137 remove accelerator keys from block and switchmotor
- functions
-- All: Fixed wrapping of messages in status line
-- All: fix parameter files for On30
-- All: fix some compiler warnings
-- All: Fix bug #137 ie. crash on in intial run
-- All: fix possible signed / unsigned char problems
-- Windows: fix some compiler warnings
-
-Version 4.2.2
-
-- All: proper initialization of gauge on initial run
-- All: Added missing Language code header in Finnish and Brazilian
- Portuguese translations
-- Linux/MacOSX Fix for string conversion issues found using
- -Wformat-security default compiler flag on modern Linux distros
-- All: Bugfix: enable changing the layer of drawing elements from
- Describe dialog
-- All: Fix formatting of parts list, use monospace font on Linux and
- OSX
-- All: fix buffer overflow bug on overly long title lines (bug 120)
-- All: Fix memory violation bug on initial run of XTrackCAD
-- All: help and message fixes, load example directories on first start
-- All: Fix cmake backwards compatibility
-- All: Fix Backspace-Handling when field is emptied completly
-- All: Suppress warning from CMake versions 3.0
-- Linux: Additional files needed for Debian packages
-
-Version 4.2.1
-
-- All: Fix problem with blank line in American prototype file
-- All: fix one occurence if undo assert bug
-- All: Fix setting and getting minimum radius in Layout Options dialog
-- Windows: add round() missing in older Visual Studio versions
-- All: Fix locale problem with Export/Import
-- Linux/OSX: fix line width when printing
-- Linux/OSX: Add text rotation to gtk/cairo
-- Windows: Fix text rotation from Describe dialog
-- Fix initial HotBar Text Issue
-- Fix shift-modify abend
-- Fix redraw on Undo and Redo
-- All: fix bug 23 - make line width independent of zoom factor a
- creation time
-- Remove Ruler Text when selecting ruler button
-- Windows: Correct size calculation for radio buttons and checkboxes
-- Fix ghosts after delete
-- Fix modify
-- Fix ghost tracks and text on mac
-- Fix color stack protection bug
-- Windows Fix Bug 108: make sure that the line width is at least 1
-- ALL Fix bug 110: Proper error message on invalid scale in parameter
- file
-- Linux: Add valid ChangeLog to the RPM package
-- fix layerlist
-- Linux: Make RPM package generator work
-- Linux/OSX Draw and print crosshair to mark center of arc
-- ALL: Complete German translation for UI, messages and demos
-- Linux/OSX Fix bug 103: Icons are unreadable
-- Linux/OSX Fix bug 101: Print command fails with path+name > 42 chars
-- fix kato-n parameter file
-- Change the default input to be the same as the default output.
-- Correction to parameter file, Marklin 5119 is a Right not a Left
- turnout
-
-Version 4.2.0
-
-- Fix I18N on Windows
-- Fix bug 48: created invalid XPMs when many colors were used
-- Windows: associate application icon to xtc files
-- Fixed installation problem on Windows 7 when profile directory did
- not exist
-- Add math library libm to link library list.
-- sscanf extra format string parameter removed
-- Changed the font size used to print XtrackCAD in the engineering
- data box.
-- Update in app/README - correct instructions for Mercurial access
-- Fixed bug 3121382 - made menu item and dialog box labeling
- consistent for custom management
-- Fix bug 3310506, 3121372 (partly) - Minimum gauge is persisted,
- gauge is automatically selected in Layout Options
-- Fixed bug 3524218: print scale is shown correctly on print out.
-- Fixed bug 3468014 - build instructions for OSX in README have been
- updated
-- Fixed bug 3535258 - Broken PostScript in German locale
-- Fixed bug 3375218 - Odometer Reads A Multiple Of Locos
-- Fixed MSVC compile problem and added missing function to mswlib
-- Updated doxygen configuration file to doxygen version 1.8.2
-- Added code to properly determine the postscript fonts occurring in
- a document.
-- Fixed the syntax of the Document Structure Comments.
-- Circle line tangent/center were interchanged
-- Fix cairo text drawing bugs by forcing painting with
- frequent redraws.
-- Locale prefix change to conform to FHS (tracker bug 3049900)
-- Internationalization support added for help button text.
-- FIX: replaced hard-coded XTRKCAD_LOCALE_DIR path with 'locale' based
- on application library directory (XTRKCAD_LOCALE_DIR is defined at
- makefiles generation time and does not reflect the place where the
- application is actually installed)
-- FIX: now it should work with CMake-2.8.1
-- Get command line parameter handling correct
-- make load last layout option work
-- Pango version check at compile time
-- Block and Switchmotor updates
-- FIX: "Gauge" translation support
-- FIX: application crash due to a double value used as a "%*" sprintf.
- scenario is "Manage" -> "Parts List..." -> "Price" (checkbox).
-- Bug fix for setting the minimum radius
-- FIX: hotbar redraw too slow under gtk-quartz
-- FIX: linux still crashed due to a cairo context access after its
- drawable destruction
-- FIX: workaround for OSX with GTK-Quartz -> pixmaps are not rendered
- when using the mask; and replaced gtk_pixmap_new deprecated function
- with gtk_image_new_from_pixmap
-- FIX: crash when displaying a non utf8 string in balloon help
-- FIX: warning removed: pointer targets in passing argument 1 of
- 'strcpy' differ in signedness
-- FIX: removed GTK run-time references to /opt/local in root directory
-- FIX: removed remained Xlib dependencies and added gtk configuration
- files when generating the OSX bundle
-- FIX: image in about dialog box was not being displayed
-- FIX: deallocate PangoFontDescription using the right function
-- FIX: EXC_BAD_ACCESS when displaying about dialog
-- ENH: replace the old font select dialog with the GTK standard one,
- and some code cleanup
-- FIX - text in layout and selection were not aligned
-- New 'About' and new icons
-- Add source for new button icons
-- LINUX Desktop File
-- New application icon
-- Improved support for bitmaps
-- New tip of the day icon
-- Enhanced bitmap display control
-- Improve internationalization support, use simple gettext on Win32
-
-
-
-INSTALLATION
-
-
-Windows
-
-XTrackCad has only been tested on Windows 7.
-
-The MS-Windows version of XTrackCad is shipped as a self-extracting/
-self-installing program using the NSIS Installer from Nullsoft Inc.
-
-Using Windows Explorer, locate the directory in which you downloaded or
-copied your new version of XTrackCAD.
-
-Start the installation program by double clicking on the
-[XTRKCAD-SETUP-4.2.4.EXE][] file icon.
-
-Follow the steps in the installation program.
-
-The installation lets you define the directory into which XTrackCAD is
-installed. The directory is created automatically if it doesn't already
-exist.
-
-A program folder named XTrackCAD 4.2.4 will be created during the
-installation process. This folder contains the program, documentation,
-parameter and example files. An existing installation of earlier
-versions of XTrackCad is not overwritten.
-
-A new program group named XTrackCad 4.2.4 will be created in the Start
-menu.
-
-
-Linux
-
-XTrackCAD for LINUX is shipped as a RPM file and a self extracting
-archive. You will need libc6, X11R6, GTK+2.0, webkitgtk.
-
-Installing from the RPM package.
-
-Use your operating system's package manager to install XTrackCAD.
-
-Installing from the self-extracting archive.
-
-After downloading open a command line then
-
- ./xtrkcad-setup-4.2.4.x86_64.sh --prefix=/usr/local --exclude-subdir
-
-This will install the executable in /usr/local/bin. A directory named
-xtrkcad will be created in /usr/local/share and all files will be
-unpacked into it.
-
-If you install XTrackCAD into another directory, set the XTRKCADLIB
-environment variable to point to that directory.
-
-
-
-RELEASE INFO
-
-
-Upgrade Information
-
-The available options for number formats have been extended. Check your
-setting in Options>Preferences
-
-
-
-BUILDING
-
-
-Overview
-
-The following instructions detail building XTrackCAD using CMake. CMake
-is a cross-platform build system, available at http://www.cmake.org,
-that can be used to generate builds for a variety of build tools ranging
-from "make" to Visual Studio and XCode. Using CMake you can build
-XTrackCAD on Windows, GNU/Linux, and Mac OSX using the build tool(s) of
-your choice.
-
-Building XTrackCAD on GNU/Linux
-
-- Obtain the current sources from Mercurial; I assume that they are
- stored locally at "~/src/xtrkcad". Note that the correct URL for
- read-only access to Mercurial is
- http://xtrkcad-fork.hg.sourceforge.net:8000/hgroot/xtrkcad-fork/xtrkcad
-- Create a separate build directory; for these instructions I assume
- that your build directory is "~/build/xtrkcad".
-- Run CMake from the build directory, passing it the path to the
- source directory:
-
- $ cd ~/build/xtrkcad $ ccmake ~/src/xtrkcad
-
-- Press the "c" key to configure the build. After a few moments you
- will see four options to configure: CMAKE_BUILD_TYPE,
- CMAKE_INSTALL_PREFIX, XTRKCAD_USE_GTK, and XTRKCAD_USE_GTK_CAIRO.
-- Use CMAKE_BUILD_TYPE to control the build type. Enter "Debug" for a
- debug build, "Release" for a release build, etc.
-- Use CMAKE_INSTALL_PREFIX to control where the software will be
- installed. For this example, I assume "~/install/xtrkcad".
-- Use XTRKCAD_USE_GETTEXT to add new locales (language translations).
- Choose "OFF" to use XTrackCAD's default language (English). Refer to
- http://www.xtrkcad.org/Wikka/Internationalization for
- additional information.
-- Use XTRKCAD_USE_GTK to control the user-interface back-end. Choose
- "OFF" for Windows, "ON" for all other platforms.
-- Use XTRKCAD_USE_GTK_CAIRO to enable optional high-quality
- antialiased Cairo rendering for the GTK back-end. This option has no
- effect unless you are using the GTK back-end.
-- Use XTRKCAD_USE_DOXYGEN to enable the production of type, function,
- etc., documentation from the the source code. Requires doxygen if
- enabled. Enable if and only if you intend to hack on the code.
-- If you made any changes, press the "c" key again to update your
- new configuration.
-- Once everything is configured to your satisfaction, press the "g"
- key to generate makefiles for your build.
-- Compile XTrkCad using your new build:
-
- $ make
-
-- Install the new binary:
-
- $ make install
-
-- Run the installed binary:
-
- $ ~/install/xtrkcad/bin/xtrkcad
-
-- If XTRKCAD_USE_DOXYGEN was enabled:
-
- $ make docs-doxygen
-
-to create the internals documentation. Read this documentation by
-pointing your web browser at
-~/build/xtrkcad/docs/doxygen/html/index.html.
-
-Building XTrackCAD on Mac OSX
-
-- You will need to install the following dependencies - I recommend
- using http://www.macports.org to obtain them:
-- GTK2
-- webkit
-- gnome-icon-theme
-- Once the prerequisites are installed the build instructions are the
- same as for the GNU/Linux build, above.
-- Remember that to run XTrackCAD on OSX, you need to have X11 running
- with your DISPLAY set.
-
-Building XTrackCAD on Windows
-
-- Obtain the current sources from Mercurial; I assume that they are
- stored locally at "c:/src/xtrkcad". Note that the correct URL for
- read-only access to Mercurial is
- http://xtrkcad-fork.hg.sourceforge.net:8000/hgroot/xtrkcad-fork/xtrkcad
-- Use the Windows Start menu to run CMake (cmake-gui).
-- Specify the source and build directories in the CMake window. You
- must provide a build directory outside the source tree - I
- use "c:/build/xtrkcad".
-- Press the "Configure" button to configure the build. You will be
- prompted for the type of build to generate. Choose your desired
- tool - I used "Visual Studio 10". After a few moments you will see
- three options to configure: CMAKE_INSTALL_PREFIX, XTRKCAD_USE_GTK,
- and XTRKCAD_USE_GTK_CAIRO.
-- Use CMAKE_INSTALL_PREFIX to control where the software will be
- installed. The default "c:/Program Files/XTrkCAD" is a good choice.
-- Use XTRKCAD_USE_GETTEXT to add new locales (language translations).
- Choose "OFF" to use XTrackCAD's default language (English). Refer to
- http://www.xtrkcad.org/Wikka/Internationalization for
- additional information.
-- Use XTRKCAD_USE_GTK to control the user-interface back-end. Choose
- "OFF" for Windows.
-- Use XTRKCAD_USE_GTK_CAIRO to enable optional high-quality
- antialiased Cairo rendering for the GTK back-end. This option has no
- effect unless on Windows.
-- Use XTRKCAD_USE_DOXYGEN to enable the production of type, function,
- etc., documentation from the the source code. Requires doxygen if
- enabled. Enable if and only if you intend to hack on the code.
-- If you made any changes, press the "Configure" button again to
- update your new configuration.
-- Once everything is configured to your satisfaction, press the "OK"
- button to generate project files for your build.
-- Compile XTrackCad using the new project files. For example, start
- MSVC and open the "XTrkCAD.sln" solution file which is located in
- your build directory.
-- Build the "BUILD_ALL" project to build the software.
-- Build the "INSTALL" project to install the software.
-- Run XTrackCAD by double-clicking its icon located in the install
- directory - for example: c:/Program Files/XTrkCAD/bin/xtrkcad.exe.
-
-
-Where to go for support
-
-The following web addresses will be helpful for any questions or bug
-reports
-
-- The Yahoo!Group mailing list
- http://groups.yahoo.com/projects/XTrkCad
-- The project website for the open source development
- http://www.xtrackcad.org/
-- The official Sourceforge site
- http://www.sourceforge.net/groups/xtrkcad-fork/
-
-Thanks for your interest in XTrackCAD.
+
+
+XTRACKCAD 4.3.0
+
+
+This file contains installation instructions and up-to-date information
+regarding XTrackCad.
+
+
+Contents
+
+- About XTrackCad
+- License Information
+- New features in this release
+- Installation
+- Upgrading from earlier releases
+- Bugs fixed
+- Building
+- Where to go for support
+
+
+About XTrackCad
+
+XTrackCad is a powerful CAD program for designing Model Railroad
+layouts.
+
+Some highlights:
+
+- Easy to use.
+- Supports any scale.
+- Supplied with parameter libraries for many popular brands of
+ turnouts, plus the capability to define your own.
+- Automatic easement (spiral transition) curve calculation.
+- Extensive help files and video-clip demonstration mode.
+
+Availability: XTrkCad Fork is a project for further development of the
+original XTrkCad software. See the project homepage at
+http://www.xtrackcad.org/ for news and current releases.
+
+
+License Information
+
+COPYING:
+
+XTrackCad is copyrighted by Dave Bullis and Martin Fischer and licensed
+as free software under the terms of the GNU General Public License v2
+which you can find in the file COPYING.
+
+
+New features
+
+Version 4.3.0
+
+- Linux: Install xtrkcad.desktop and xtrkcad.png for desktop
+ integration
+- All: Fix color button initialization
+- Add control and sensor types
+- Development of signal feature was finished
+- Add extra AppleHelp files
+- All: Add documentation for layout control elements
+- Write proper Describe, Move, and Rotate functions for Signals.
+- Add high lighting for signals.
+- Add AppleHelp bundle generation including index
+- First pass at high lighting layout control elements.
+- Linux/OSX: Set directory for rc file
+- All: Rework DXF export, add support for metric measurements
+- All: Add dynstring to build and modify DynstrMalloc interface
+- All: Add dynstring library and unit tests
+- All: enable unit testing with CMocka
+- Add Layout Control Element management dialog
+
+Version 4.2.4
+
+- All: Parameter file for Minitrains HOe-009-HOn30 Track System
+- All: Improved and new parameter files Kato N and Super O
+- All: Corrected parameter file for Peco HOn30/OO9 track
+- All: New parameter file for Peco HOn3 turnouts
+- All: New and updated parameter files for Z-scale
+- All: added a few more length formats
+- All: added additional zoom and marco zoom steps
+- All: Increase meximum number of layer buttons to 99
+- All: The parameter file dialog now allows loading and unloading
+ several files together
+
+Version 4.2.3
+
+- All: updated German translations
+- All: TT Kuehn added items
+- Linux/OSX: New printing system
+- All: tomix-n.xtp Added or Updated multiple items
+- All: Add length format with six decimal places for English units
+ (feature wish #33)
+- All: Feature Request #35: add hotkey for switching map window on and
+ off
+- All: Make the installation's param directory the default on initial
+ run
+- All: several new and updated parameter files
+- All: add Nm gauge and some Nm track parameters
+
+Version 4.2.2
+
+- All: Update German translations
+- All: extended parameter files f𲠋ato HO and Walthers N structures
+- All: Added and extended parameter files
+- All: Add support for HOf scale/gauge and Busch track parameter files
+- Linux/OSX: Replace file selector dialog with newer file chooser
+ dialog
+- All: Make editing of custom track work
+- All: Fix Atlas HO Code 100 parameter file
+- All: new Kato Unitrack N-Scale parameter file
+- All: add measurement units to train speed
+
+Version 4.2.1
+
+- Increase the number of layer buttons to 99
+- All: Update Eishindo T Gauge parameter file
+- All: Paste clipboard content at position of mouse pointer
+- All: Never mark curve centers of turnouts
+- All: Make drawing of center markings (crosshair) an user option
+- add ability to set text color when creating them
+- Windows: Draw and print crosshair to mark the center of an arc
+- Add the ability to change layers of a piece of track in the
+ describe box.
+
+Version 4.2.0
+
+- New and updated parameter files and layout examples
+- Apply user preferences for dimensions to elevations
+- Add ability to update color of Text in properties
+- Fix compile problem on FreeBSD
+- Fix Oracle Solaris Studio 12.3 warnings
+- partially completed Brazilian Portuguese translation (57%)
+- Improve German translations
+- Merged webkit help system from Debian
+- Update help CSS to the Wiki's new default look
+
+
+Bugs fixed
+
+Version 4.3.0
+
+- All: Save and set user defined values for Text command
+- All: Fix path handling error after Save/Save As
+- All: Fix color button initialization
+- Fix Malloc error (wrong size in ReadBlock, causing Guard1
+ hose error)
+- Updated cblock.c and cswitchmotor.c to handle possible broken blocks
+ and switchmotors and not crash (check for NULL pointers)
+- Bulletproof against undefined (NULL pointer) track segments in
+ SwitchMotor code.
+- Bulletproof against undefined (NULL pointer) track segments in
+ Block code.
+- Linux/OSX: Preparing for GTK3 migration, second set of changes
+- Clean up help files for Apple Help Indexer
+- Linux/OSX: Preparing for GTK3 migration, first set of changes
+- All: New and updated parameter files for Lego and Peco H0 Code 83
+- Linux/OSX: Add OSX specific files
+- Linux/OSX: Split help functions in generic and platform specific
+ piece
+- Description: Correct some translation typos
+- Linux/OSX: Fix #163 GCC format-security errors
+- All: Update parameter file for Kuehn TT track
+- Add forward reference resolution for Blocks and Switchmotors
+- Cleanly delete blocks and switch motors when their tracks are
+ deleted (avoid dangling pointers)
+- Updated Spec file
+- Expand help path name for longer bundle directories
+- Attempt to fix help files crash issue
+- Add GLIB Schemas to GTK-Bundle
+- All: Improved German translations
+- Update Readme for OSX package
+- Add support for gtk-mac-bundler
+- fix bugs in xtrkcad-bundler code
+- Fix parm dialog default for GTK builds
+- Add a post-build script for auto-creating OSX images
+- Remove failing copy command for gtk-bundle share
+- Linux/OSX: Fix uninitialized param file directory on first run
+- All: Add TTi scale / gauge
+- All: New paramter files for Frateschi HO and Auhagen TTi
+
+Version 4.2.4a
+
+- All: Update help
+- Linux: Installation from self extracting archive accepts install
+ path
+- Linux/OSX: Remove absolute path from source packages
+- All: remove all dependencies on obsolete XTRKCAD_USE_LAYOUTCONTROL
+ conditional
+- All: New parameter file for Micro Engineering HOn3 Turnouts
+- Windows: Fix bug 157 Crash on color change when drawing lines
+- All: Updated parameter file for Kato N scale
+- All: Fix build problem with block and switchmotor feature
+
+Version 4.2.4
+
+- Linux/OSX: Correct search order for config files
+- All: Layout control functions are always included
+- Linux/OSX: add a default file extension when none is present on save
+- Linux/OSX: Update package build
+- All: Fix compiler warnings for pointer to in casts on 64 bit systems
+- All: Correct file comments
+- All: Consistent spelling
+- All: Fix definition for Atlas Code 83 3/4" straight track
+
+Version 4.2.3b
+
+- Windows: Fix numeric overflow when reading layouts created on Linux
+- Linux/OSX: Fix crash when closing Train Control window
+- Linux/OSX: Fix crash when closing Change Elevation Window
+- All: new and improved parameter files for Tillig track
+
+Version 4.2.3a
+
+- Windows: Make UI translation work with directory structure of 64 bit
+ Windows
+- Linux/OSX: Use defaults for printer and page settings on first run
+
+Version 4.2.3
+
+- All: Fix bug #143: Roco N Turnout 22247
+- All: fix invalid const variable usage
+- Linux/OSX: cairo is required and no longer optional
+- All: Fix bug #137 remove accelerator keys from block and switchmotor
+ functions
+- All: Fixed wrapping of messages in status line
+- All: fix parameter files for On30
+- All: fix some compiler warnings
+- All: Fix bug #137 ie. crash on in intial run
+- All: fix possible signed / unsigned char problems
+- Windows: fix some compiler warnings
+
+Version 4.2.2
+
+- All: proper initialization of gauge on initial run
+- All: Added missing Language code header in Finnish and Brazilian
+ Portuguese translations
+- Linux/MacOSX Fix for string conversion issues found using
+ -Wformat-security default compiler flag on modern Linux distros
+- All: Bugfix: enable changing the layer of drawing elements from
+ Describe dialog
+- All: Fix formatting of parts list, use monospace font on Linux and
+ OSX
+- All: fix buffer overflow bug on overly long title lines (bug 120)
+- All: Fix memory violation bug on initial run of XTrackCAD
+- All: help and message fixes, load example directories on first start
+- All: Fix cmake backwards compatibility
+- All: Fix Backspace-Handling when field is emptied completly
+- All: Suppress warning from CMake versions 3.0
+- Linux: Additional files needed for Debian packages
+
+Version 4.2.1
+
+- All: Fix problem with blank line in American prototype file
+- All: fix one occurence if undo assert bug
+- All: Fix setting and getting minimum radius in Layout Options dialog
+- Windows: add round() missing in older Visual Studio versions
+- All: Fix locale problem with Export/Import
+- Linux/OSX: fix line width when printing
+- Linux/OSX: Add text rotation to gtk/cairo
+- Windows: Fix text rotation from Describe dialog
+- Fix initial HotBar Text Issue
+- Fix shift-modify abend
+- Fix redraw on Undo and Redo
+- All: fix bug 23 - make line width independent of zoom factor a
+ creation time
+- Remove Ruler Text when selecting ruler button
+- Windows: Correct size calculation for radio buttons and checkboxes
+- Fix ghosts after delete
+- Fix modify
+- Fix ghost tracks and text on mac
+- Fix color stack protection bug
+- Windows Fix Bug 108: make sure that the line width is at least 1
+- ALL Fix bug 110: Proper error message on invalid scale in parameter
+ file
+- Linux: Add valid ChangeLog to the RPM package
+- fix layerlist
+- Linux: Make RPM package generator work
+- Linux/OSX Draw and print crosshair to mark center of arc
+- ALL: Complete German translation for UI, messages and demos
+- Linux/OSX Fix bug 103: Icons are unreadable
+- Linux/OSX Fix bug 101: Print command fails with path+name > 42 chars
+- fix kato-n parameter file
+- Change the default input to be the same as the default output.
+- Correction to parameter file, Marklin 5119 is a Right not a Left
+ turnout
+
+Version 4.2.0
+
+- Fix I18N on Windows
+- Fix bug 48: created invalid XPMs when many colors were used
+- Windows: associate application icon to xtc files
+- Fixed installation problem on Windows 7 when profile directory did
+ not exist
+- Add math library libm to link library list.
+- sscanf extra format string parameter removed
+- Changed the font size used to print XtrackCAD in the engineering
+ data box.
+- Update in app/README - correct instructions for Mercurial access
+- Fixed bug 3121382 - made menu item and dialog box labeling
+ consistent for custom management
+- Fix bug 3310506, 3121372 (partly) - Minimum gauge is persisted,
+ gauge is automatically selected in Layout Options
+- Fixed bug 3524218: print scale is shown correctly on print out.
+- Fixed bug 3468014 - build instructions for OSX in README have been
+ updated
+- Fixed bug 3535258 - Broken PostScript in German locale
+- Fixed bug 3375218 - Odometer Reads A Multiple Of Locos
+- Fixed MSVC compile problem and added missing function to mswlib
+- Updated doxygen configuration file to doxygen version 1.8.2
+- Added code to properly determine the postscript fonts occurring in
+ a document.
+- Fixed the syntax of the Document Structure Comments.
+- Circle line tangent/center were interchanged
+- Fix cairo text drawing bugs by forcing painting with
+ frequent redraws.
+- Locale prefix change to conform to FHS (tracker bug 3049900)
+- Internationalization support added for help button text.
+- FIX: replaced hard-coded XTRKCAD_LOCALE_DIR path with 'locale' based
+ on application library directory (XTRKCAD_LOCALE_DIR is defined at
+ makefiles generation time and does not reflect the place where the
+ application is actually installed)
+- FIX: now it should work with CMake-2.8.1
+- Get command line parameter handling correct
+- make load last layout option work
+- Pango version check at compile time
+- Block and Switchmotor updates
+- FIX: "Gauge" translation support
+- FIX: application crash due to a double value used as a "%*" sprintf.
+ scenario is "Manage" -> "Parts List..." -> "Price" (checkbox).
+- Bug fix for setting the minimum radius
+- FIX: hotbar redraw too slow under gtk-quartz
+- FIX: linux still crashed due to a cairo context access after its
+ drawable destruction
+- FIX: workaround for OSX with GTK-Quartz -> pixmaps are not rendered
+ when using the mask; and replaced gtk_pixmap_new deprecated function
+ with gtk_image_new_from_pixmap
+- FIX: crash when displaying a non utf8 string in balloon help
+- FIX: warning removed: pointer targets in passing argument 1 of
+ 'strcpy' differ in signedness
+- FIX: removed GTK run-time references to /opt/local in root directory
+- FIX: removed remained Xlib dependencies and added gtk configuration
+ files when generating the OSX bundle
+- FIX: image in about dialog box was not being displayed
+- FIX: deallocate PangoFontDescription using the right function
+- FIX: EXC_BAD_ACCESS when displaying about dialog
+- ENH: replace the old font select dialog with the GTK standard one,
+ and some code cleanup
+- FIX - text in layout and selection were not aligned
+- New 'About' and new icons
+- Add source for new button icons
+- LINUX Desktop File
+- New application icon
+- Improved support for bitmaps
+- New tip of the day icon
+- Enhanced bitmap display control
+- Improve internationalization support, use simple gettext on Win32
+
+
+
+INSTALLATION
+
+
+Windows
+
+XTrackCad has only been tested on Windows 7.
+
+The MS-Windows version of XTrackCad is shipped as a self-extracting/
+self-installing program using the NSIS Installer from Nullsoft Inc.
+
+Using Windows Explorer, locate the directory in which you downloaded or
+copied your new version of XTrackCAD.
+
+Start the installation program by double clicking on the
+[XTRKCAD-SETUP-4.3.0.EXE][] file icon.
+
+Follow the steps in the installation program.
+
+The installation lets you define the directory into which XTrackCAD is
+installed. The directory is created automatically if it doesn't already
+exist.
+
+A program folder named XTrackCAD 4.3.0 will be created during the
+installation process. This folder contains the program, documentation,
+parameter and example files. An existing installation of earlier
+versions of XTrackCad is not overwritten.
+
+A new program group named XTrackCad 4.3.0 will be created in the Start
+menu.
+
+
+Linux
+
+XTrackCAD for LINUX is shipped as a RPM file and a self extracting
+archive. You will need libc6, X11R6, GTK+2.0, webkitgtk.
+
+Installing from the RPM package.
+
+Use your operating system's package manager to install XTrackCAD.
+
+Installing from the self-extracting archive.
+
+After downloading open a command line then
+
+ ./xtrkcad-setup-4.3.0.x86_64.sh --prefix=/usr/local --exclude-subdir
+
+This will install the executable in /usr/local/bin. A directory named
+xtrkcad will be created in /usr/local/share and all files will be
+unpacked into it.
+
+If you install XTrackCAD into another directory, set the XTRKCADLIB
+environment variable to point to that directory.
+
+
+
+RELEASE INFO
+
+
+Upgrade Information
+
+The available options for number formats have been extended. Check your
+setting in Options>Preferences
+
+
+
+BUILDING
+
+
+Overview
+
+The following instructions detail building XTrackCAD using CMake. CMake
+is a cross-platform build system, available at http://www.cmake.org,
+that can be used to generate builds for a variety of build tools ranging
+from "make" to Visual Studio and XCode. Using CMake you can build
+XTrackCAD on Windows, GNU/Linux, and Mac OSX using the build tool(s) of
+your choice.
+
+Building XTrackCAD on GNU/Linux
+
+- Obtain the current sources from Mercurial; I assume that they are
+ stored locally at "~/src/xtrkcad". Note that the correct URL for
+ read-only access to Mercurial is
+ http://xtrkcad-fork.hg.sourceforge.net:8000/hgroot/xtrkcad-fork/xtrkcad
+- Create a separate build directory; for these instructions I assume
+ that your build directory is "~/build/xtrkcad".
+- Run CMake from the build directory, passing it the path to the
+ source directory:
+
+ $ cd ~/build/xtrkcad $ ccmake ~/src/xtrkcad
+
+- Press the "c" key to configure the build. After a few moments you
+ will see four options to configure: CMAKE_BUILD_TYPE,
+ CMAKE_INSTALL_PREFIX, XTRKCAD_USE_GTK, and XTRKCAD_USE_GTK_CAIRO.
+- Use CMAKE_BUILD_TYPE to control the build type. Enter "Debug" for a
+ debug build, "Release" for a release build, etc.
+- Use CMAKE_INSTALL_PREFIX to control where the software will be
+ installed. For this example, I assume "~/install/xtrkcad".
+- Use XTRKCAD_USE_GETTEXT to add new locales (language translations).
+ Choose "OFF" to use XTrackCAD's default language (English). Refer to
+ http://www.xtrkcad.org/Wikka/Internationalization for
+ additional information.
+- Use XTRKCAD_USE_GTK to control the user-interface back-end. Choose
+ "OFF" for Windows, "ON" for all other platforms.
+- Use XTRKCAD_USE_GTK_CAIRO to enable optional high-quality
+ antialiased Cairo rendering for the GTK back-end. This option has no
+ effect unless you are using the GTK back-end.
+- Use XTRKCAD_USE_DOXYGEN to enable the production of type, function,
+ etc., documentation from the the source code. Requires doxygen if
+ enabled. Enable if and only if you intend to hack on the code.
+- If you made any changes, press the "c" key again to update your
+ new configuration.
+- Once everything is configured to your satisfaction, press the "g"
+ key to generate makefiles for your build.
+- Compile XTrkCad using your new build:
+
+ $ make
+
+- Install the new binary:
+
+ $ make install
+
+- Run the installed binary:
+
+ $ ~/install/xtrkcad/bin/xtrkcad
+
+- If XTRKCAD_USE_DOXYGEN was enabled:
+
+ $ make docs-doxygen
+
+to create the internals documentation. Read this documentation by
+pointing your web browser at
+~/build/xtrkcad/docs/doxygen/html/index.html.
+
+Building XTrackCAD on Mac OSX
+
+- You will need to install the following dependencies - I recommend
+ using http://www.macports.org to obtain them:
+- GTK2
+- webkit
+- gnome-icon-theme
+- Once the prerequisites are installed the build instructions are the
+ same as for the GNU/Linux build, above.
+- Remember that to run XTrackCAD on OSX, you need to have X11 running
+ with your DISPLAY set.
+
+Building XTrackCAD on Windows
+
+- Obtain the current sources from Mercurial; I assume that they are
+ stored locally at "c:/src/xtrkcad". Note that the correct URL for
+ read-only access to Mercurial is
+ http://xtrkcad-fork.hg.sourceforge.net:8000/hgroot/xtrkcad-fork/xtrkcad
+- Use the Windows Start menu to run CMake (cmake-gui).
+- Specify the source and build directories in the CMake window. You
+ must provide a build directory outside the source tree - I
+ use "c:/build/xtrkcad".
+- Press the "Configure" button to configure the build. You will be
+ prompted for the type of build to generate. Choose your desired
+ tool - I used "Visual Studio 10". After a few moments you will see
+ three options to configure: CMAKE_INSTALL_PREFIX, XTRKCAD_USE_GTK,
+ and XTRKCAD_USE_GTK_CAIRO.
+- Use CMAKE_INSTALL_PREFIX to control where the software will be
+ installed. The default "c:/Program Files/XTrkCAD" is a good choice.
+- Use XTRKCAD_USE_GETTEXT to add new locales (language translations).
+ Choose "OFF" to use XTrackCAD's default language (English). Refer to
+ http://www.xtrkcad.org/Wikka/Internationalization for
+ additional information.
+- Use XTRKCAD_USE_GTK to control the user-interface back-end. Choose
+ "OFF" for Windows.
+- Use XTRKCAD_USE_GTK_CAIRO to enable optional high-quality
+ antialiased Cairo rendering for the GTK back-end. This option has no
+ effect unless on Windows.
+- Use XTRKCAD_USE_DOXYGEN to enable the production of type, function,
+ etc., documentation from the the source code. Requires doxygen if
+ enabled. Enable if and only if you intend to hack on the code.
+- If you made any changes, press the "Configure" button again to
+ update your new configuration.
+- Once everything is configured to your satisfaction, press the "OK"
+ button to generate project files for your build.
+- Compile XTrackCad using the new project files. For example, start
+ MSVC and open the "XTrkCAD.sln" solution file which is located in
+ your build directory.
+- Build the "BUILD_ALL" project to build the software.
+- Build the "INSTALL" project to install the software.
+- Run XTrackCAD by double-clicking its icon located in the install
+ directory - for example: c:/Program Files/XTrkCAD/bin/xtrkcad.exe.
+
+
+Where to go for support
+
+The following web addresses will be helpful for any questions or bug
+reports
+
+- The Yahoo!Group mailing list
+ http://groups.yahoo.com/projects/XTrkCad
+- The project website for the open source development
+ http://www.xtrackcad.org/
+- The official Sourceforge site
+ http://www.sourceforge.net/groups/xtrkcad-fork/
+
+Thanks for your interest in XTrackCAD.
diff --git a/app/lib/astylerc b/app/lib/astylerc
new file mode 100644
index 0000000..e0815ce
--- /dev/null
+++ b/app/lib/astylerc
@@ -0,0 +1,8 @@
+style=1tbs
+break-blocks
+unpad-paren
+pad-header
+max-code-length=80
+break-after-logical
+mode=c
+
diff --git a/app/lib/params/HO-Frateschi.xtp b/app/lib/params/HO-Frateschi.xtp
new file mode 100644
index 0000000..60b63eb
--- /dev/null
+++ b/app/lib/params/HO-Frateschi.xtp
@@ -0,0 +1,196 @@
+CONTENTS Frateschi HO Track
+SUBCONTENTS Frateschi HO Track - Straight
+TURNOUT HO "Frateschi HO Track Straight 880mm 4880/4980"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 34.645669 0.000000 90.000000
+ S 0 0.000000 0.000000 0.000000 34.645669 0.000000
+END
+TURNOUT HO "Frateschi HO Track Straight 220mm 4220/4920"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 8.661417 0.000000 90.000000
+ S 0 0.000000 0.000000 0.000000 8.661417 0.000000
+END
+TURNOUT HO "Frateschi HO Track Straight 110mm 4110/4910"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 4.330709 0.000000 90.000000
+ S 0 0.000000 0.000000 0.000000 4.330709 0.000000
+END
+TURNOUT HO "Frateschi HO Track Straight 55mm 4055/4955"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 2.165354 0.000000 90.000000
+ S 0 0.000000 0.000000 0.000000 2.165354 0.000000
+END
+TURNOUT HO "Frateschi HO Track Straight(old geometry) 45mm 4045"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 1.771654 0.000000 90.000000
+ S 0 0.000000 0.000000 0.000000 1.771654 0.000000
+END
+SUBCONTENTS Frateschi HO Track - Misc
+TURNOUT HO "Frateschi HO Track Uncoupler Straight 110mm 4110D/4910D"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 4.330709 0.000000 90.000000
+ S 0 0.000000 0.000000 0.000000 4.330709 0.000000
+ F 0 0.000000 4
+ 1.443570 0.250000 0
+ 2.887139 0.250000 0
+ 2.887139 -0.250000 0
+ 1.443570 -0.250000 0
+END
+STRUCTURE HO "Frateschi HO Track Bumper 1525"
+ X pier 0.000000 "B"
+ L 0 0.100000 0.000000 0.300000 -1.000000 0.300000
+ L 0 0.100000 -0.500000 0.600000 -0.500000 -0.600000
+ L 0 0.100000 0.000000 -0.300000 -1.000000 -0.300000
+END
+SUBCONTENTS Frateschi HO Track - Curve
+TURNOUT HO "Frateschi HO Track Curve 360mm 30 4188/4988"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 7.086614 -1.898853 120.000000
+ C 0 0.000000 14.173228 0.000000 -14.173228 0.000000 30.000000
+END
+TURNOUT HO "Frateschi HO Track Curve 418mm 30 4219/4919"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 8.228346 -2.204779 120.000000
+ C 0 0.000000 16.456693 0.000000 -16.456693 0.000000 30.000000
+END
+TURNOUT HO "Frateschi HO Track Curve 480mm 20 4166/4966"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 6.463373 -1.139667 110.000000
+ C 0 0.000000 18.897638 0.000000 -18.897638 0.000000 20.000000
+END
+TURNOUT HO "Frateschi HO Track Curve 480mm 10 4083/4983"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 3.281540 -0.287098 100.000000
+ C 0 0.000000 18.897638 0.000000 -18.897638 0.000000 10.000000
+END
+TURNOUT HO "Frateschi HO Track Curve(old) 482mm 20 4166"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 6.490304 -1.144416 110.000000
+ C 0 0.000000 18.976378 0.000000 -18.976378 0.000000 20.000000
+END
+TURNOUT HO "Frateschi HO Track Curve(old) 482mm 10 4083"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 3.295213 -0.288294 100.000000
+ C 0 0.000000 18.976378 0.000000 -18.976378 0.000000 10.000000
+END
+SUBCONTENTS Frateschi HO Track - Turnouts
+TURNOUT HO "Frateschi HO Track Left Remote Turnout 4200L/4900L"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 8.661417 0.000000 90.000000
+ E 8.661417 1.141732 75.000000
+ S 0 0.000000 0.000000 0.000000 0.649600 0.000000
+ S 0 0.000000 0.649600 0.000000 8.661417 0.000000
+ C 0 0.000000 -28.490603 0.649638 28.490603 164.999924 15.000152
+ S 0 0.000000 8.023578 0.970812 8.661417 1.141732
+ F 0 0.000000 6
+ 2.887139 -0.600000 0
+ 5.774278 -0.600000 0
+ 5.774278 -1.050000 0
+ 5.574278 -1.250000 0
+ 3.087139 -1.250000 0
+ 2.887139 -1.050000 0
+END
+TURNOUT HO "Frateschi HO Track Curve 850mm 15 4222/4922"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 8.661267 -1.140277 105.000000
+ C 0 0.000000 33.464567 0.000000 -33.464567 0.000000 15.000000
+END
+TURNOUT HO "Frateschi HO Track Right Remote Turnout 4200R/4900R"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 8.661417 0.000000 90.000000
+ E 8.661417 -1.141732 105.000000
+ S 0 0.000000 0.000000 0.000000 0.649600 0.000000
+ S 0 0.000000 0.649600 0.000000 8.661417 0.000000
+ C 0 0.000000 28.490603 0.649487 -28.490603 0.000076 15.000152
+ S 0 0.000000 8.023578 -0.970812 8.661417 -1.141732
+ F 0 0.000000 6
+ 2.887139 0.600000 0
+ 5.774278 0.600000 0
+ 5.774278 1.050000 0
+ 5.574278 1.250000 0
+ 3.087139 1.250000 0
+ 2.887139 1.050000 0
+END
+TURNOUT HO "Frateschi HO Track Left Turnout (OLD) 4165L"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 6.496063 0.000000 90.000000
+ E 6.496063 1.144416 70.000000
+ S 0 0.000000 0.000000 0.000000 0.655402 0.000000
+ S 0 0.000000 0.655402 0.000000 6.496063 0.000000
+ C 0 0.000000 -15.292205 0.655422 15.292205 159.999924 20.000152
+ S 0 0.000000 5.885678 0.922245 6.496063 1.144416
+END
+TURNOUT HO "Frateschi HO Track Right Turnout (OLD) 4165R"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 6.496063 0.000000 90.000000
+ E 6.496063 -1.144416 110.000000
+ S 0 0.000000 0.000000 0.000000 0.655402 0.000000
+ S 0 0.000000 0.655402 0.000000 6.496063 0.000000
+ C 0 0.000000 15.292205 0.655341 -15.292205 0.000076 20.000152
+ S 0 0.000000 5.885678 -0.922245 6.496063 -1.144416
+END
+SUBCONTENTS Frateschi HO Track - TurnTable
+TURNOUT HO "Frateschi Turntable 220mm 20d 4500"
+ P "1" 1
+ P "2" 2
+ P "3" 3
+ P "4" 4
+ P "5" 5
+ P "6" 6
+ P "7" 7
+ P "8" 8
+ P "9" 9
+ E 0.000000 0.000000 180.000000
+ E 0.000000 4.330709 0.000000
+ E 1.481190 4.069535 20.000000
+ E 2.783726 3.317515 40.000000
+ E 3.750504 2.165354 60.000000
+ E 4.264915 0.752020 80.000000
+ E 4.264915 -0.752020 100.000000
+ E 3.750504 -2.165354 120.000000
+ E 2.783726 -3.317515 140.000000
+ E 1.481190 -4.069535 160.000000
+ E 0.000000 -4.330709 180.000000
+ E -1.481190 -4.069535 200.000000
+ E -2.783726 -3.317515 220.000000
+ E -3.750504 -2.165354 240.000000
+ E -4.264915 -0.752020 260.000000
+ E -4.264915 0.752020 280.000000
+ E -3.750504 2.165354 300.000000
+ E -2.783726 3.317515 320.000000
+ E -1.481190 4.069535 340.000000
+ S 16777215 0 0.000000 4.330709 0.000000 -4.330709
+ S 16777215 0 1.481190 4.069535 -1.481190 -4.069535
+ S 16777215 0 2.783726 3.317515 -2.783726 -3.317515
+ S 16777215 0 3.750504 2.165354 -3.750504 -2.165354
+ S 16777215 0 4.264915 0.752020 -4.264915 -0.752020
+ S 16777215 0 4.264915 -0.752020 -4.264915 0.752020
+ S 16777215 0 3.750504 -2.165354 -3.750504 2.165354
+ S 16777215 0 2.783726 -3.317515 -2.783726 3.317515
+ S 16777215 0 1.481190 -4.069535 -1.481190 4.069535
+ A 0 0.031250 4.330709 0.000000 0.000000 0.000000 360.000000
+ A 0 0.031250 5.080709 0.000000 0.000000 0.000000 360.000000
+ A 0 0.031250 1.377727 0.000000 0.000000 0.000000 360.000000
+ G 0 0.000000 0.750000 0.000000 0.000000 0.000000 360.000000
+END \ No newline at end of file
diff --git a/app/lib/params/HOn3-BlackStoneProTraxx.xtp b/app/lib/params/HOn3-BlackStoneProTraxx.xtp
new file mode 100644
index 0000000..d47e2b8
--- /dev/null
+++ b/app/lib/params/HOn3-BlackStoneProTraxx.xtp
@@ -0,0 +1,21 @@
+CONTENTS Blackstone ProTraxx HOn3 Snap-Track
+
+SUBCONTENTS Blackstone ProTraxx HOn3 Snap-Track - Straight Track
+TURNOUT HOn3 "ProTraxx HOn3 Snap-Track Straight 6.535 228mm B500100"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 8.976378 0.000000 90.000000
+ S 0 0 0.000000 0.000000 8.976378 0.000000
+ L 11579568 0.053333 0.000000 0.629921 8.976378 0.629921
+ L 11579568 0.053333 0.000000 -0.629921 8.976378 -0.629921
+END
+
+SUBCONTENTS Blackstone ProTraxx HOn3 Snap-Track - Curve Track
+TURNOUT HOn3 "ProTraxx HOn3 Snap-Track Curve 18.90R 480mm 22.5 B500200"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 7.231813 -1.438497 112.500000
+ C 0 0 18.897638 0.000000 -18.897638 0.000000 22.500000
+ A 11579568 0.053333 18.267717 0.000000 -18.897638 0.000000 22.500000
+ A 11579568 0.053333 19.527559 0.000000 -18.897638 0.000000 22.500000
+END
diff --git a/app/lib/params/Lego-Track.xtp b/app/lib/params/Lego-Track.xtp
new file mode 100644
index 0000000..784635a
--- /dev/null
+++ b/app/lib/params/Lego-Track.xtp
@@ -0,0 +1,152 @@
+CONTENTS Lego Track Components
+# Created By Dwyane Ward 01Jan2013
+
+SUBCONTENTS Lego - 9V Track
+TURNOUT LEGO "Lego Straight Track (9V) 2865/4515"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 5.039370 0.000000 90.000000
+ S 0 0.000000 0.000000 0.000000 5.039370 0.000000
+ END
+TURNOUT LEGO "Lego Curve Track (9V) 28674520"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 4.821209 0.958998 67.500000
+ C 0 0.000000 -12.598425 0.000000 12.598425 157.500000 22.500000
+ END
+TURNOUT LEGO "Lego Crossing Track (9V) 320874519"
+ P "Normal" 1 0 2
+ E 0.000000 0.000000 270.000000
+ E 5.039370 0.000000 90.000000
+ E 2.519692 2.519685 0.000000
+ E 2.519678 -2.519685 180.000000
+ S 0 0.000000 0.000000 0.000000 5.039370 0.000000
+ S 0 0.000000 2.519692 2.519685 2.519678 -2.519685
+ END
+TURNOUT LEGO "Lego Left Switch (9V) 2861/4531"
+ P "P0" 1 5 4 3
+ P "P1" 2
+ E 0.000000 0.000000 270.000000
+ E 10.078740 -0.000027 90.000000
+ E 10.236648 4.068369 67.500000
+ C 0 0.000000 -6.377953 0.000017 6.377953 166.446760 13.553240
+ S 0 0.000000 0.000000 0.000000 10.078740 -0.000027
+ C 0 0.000000 6.377953 12.677383 -1.824092 323.058181 14.441819
+ C 0 0.000000 -15.666120 -0.571293 15.794471 143.057808 23.388952
+ S 0 0.000000 1.494665 0.177605 3.100081 0.564621
+ END
+TURNOUT LEGO "Lego Right Switch (9V) 2859/4531"
+ P "P0" 1 5 4 3
+ P "P1" 2
+ E 0.000000 0.000000 269.999924
+ E 10.078723 0.000000 90.000000
+ E -0.157881 4.068390 292.500000
+ C 0 0.000000 6.377953 10.078740 6.377953 180.000000 13.553240
+ S 0 0.000000 10.078740 0.000000 0.000000 0.000000
+ C 0 0.000000 -6.377953 -2.598648 -1.824058 22.500000 14.441819
+ C 0 0.000000 15.666120 10.650075 15.794470 193.553240 23.388952
+ S 0 0.000000 8.584076 0.177609 6.978661 0.564629
+ END
+
+SUBCONTENTS Lego - 12V Track
+TURNOUT LEGO "Lego Straight Track (12V) 3242"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 5.039370 0.000000 90.000000
+ S 0 0.000000 0.000000 0.000000 5.039370 0.000000
+ END
+TURNOUT LEGO "Lego Curve Track (12V) 3241"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 4.821209 0.958998 67.500000
+ C 0 0.000000 -12.598425 0.000000 12.598425 157.500000 22.500000
+ END
+TURNOUT LEGO "Lego Crossing Track (12V) 3232"
+ P "Normal" 1 0 2
+ E 0.000000 0.000000 270.000000
+ E 5.039370 0.000000 90.000000
+ E 2.519692 2.519685 360.000000
+ E 2.519678 -2.519685 180.000000
+ S 0 0.000000 0.000000 0.000000 5.039370 0.000000
+ S 0 0.000000 2.519692 2.519685 2.519678 -2.519685
+ END
+TURNOUT LEGO "Lego Left Switch (12V) 73697/7859"
+ P "P0" 1
+ P "P1" 2 3 4
+ E 0.000000 0.000000 270.000000
+ E 10.078740 2.519685 90.000000
+ E 10.078740 0.000000 90.000000
+ S 0 0.000000 0.000000 0.000000 10.078740 0.000000
+ C 0 0.000000 -10.236220 0.000000 10.236220 156.774050 23.225950
+ S 0 0.000000 4.036786 0.829585 6.042006 1.690111
+ C 0 0.000000 10.236220 10.078740 -7.716535 336.774050 23.225950
+ END
+TURNOUT LEGO "Lego Right Switch (12V) 73696/7859"
+ P "P0" 1
+ P "P1" 2 3 4
+ E 0.000000 0.000000 270.000000
+ E 0.000000 2.519685 270.000000
+ E 10.078740 0.000000 90.000000
+ S 0 0.000000 0.000000 0.000000 10.078740 0.000000
+ C 0 0.000000 10.236220 10.078740 10.236220 180.000000 23.225950
+ S 0 0.000000 6.042006 0.829585 4.036787 1.690111
+ C 0 0.000000 -10.236220 0.000000 -7.716535 0.000000 23.225950
+ END
+
+SUBCONTENTS Lego - RC Track
+TURNOUT LEGO "Lego Straight Track (RC) 53401"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 5.039370 0.000000 90.000000
+ S 0 0.000000 0.000000 0.000000 5.039370 0.000000
+ END
+TURNOUT LEGO "Lego Curve Track (RC) 53400"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 4.821209 0.958998 67.500000
+ C 0 0.000000 -12.598425 0.000000 12.598425 157.500000 22.500000
+ END
+TURNOUT LEGO "Lego Left Switch (RC) 53407"
+ P "P0" 1 5 4 3
+ P "P1" 2
+ E 0.000000 0.000000 270.000000
+ E 10.078740 -0.000027 90.000000
+ E 10.236648 4.068369 67.500000
+ C 0 0.000000 -6.377953 0.000017 6.377953 166.446760 13.553240
+ S 0 0.000000 0.000000 0.000000 10.078740 -0.000027
+ C 0 0.000000 6.377953 12.677383 -1.824092 323.058181 14.441819
+ C 0 0.000000 -15.666120 -0.571293 15.794471 143.057808 23.388952
+ S 0 0.000000 1.494665 0.177605 3.100081 0.564621
+ END
+TURNOUT LEGO "Lego Right Switch (RC) 53404"
+ P "P0" 1 5 4 3
+ P "P1" 2
+ E 0.000000 0.000000 269.999924
+ E 10.078723 0.000000 90.000000
+ E -0.157881 4.068390 292.500000
+ C 0 0.000000 6.377953 10.078740 6.377953 180.000000 13.553240
+ S 0 0.000000 10.078740 0.000000 0.000000 0.000000
+ C 0 0.000000 -6.377953 -2.598648 -1.824058 22.500000 14.441819
+ C 0 0.000000 15.666120 10.650075 15.794470 193.553240 23.388952
+ S 0 0.000000 8.584076 0.177609 6.978661 0.564629
+ END
+TURNOUT LEGO "Lego Double Crossover (RC) 60128"
+ P "Normal" 1 2 3 0 4 5 6
+ P "Reverse" 1 7 8 9 6 0 4 10 11 12 3
+ E 0.000000 0.000000 270.000000
+ E 15.118110 0.000000 90.000000
+ E 0.000000 5.039370 270.000000
+ E 15.118110 5.039370 90.000000
+ S 0 0.000000 0.000000 0.000000 2.220991 0.000000
+ S 0 0.000000 2.220991 0.000000 12.897119 0.000000
+ S 0 0.000000 12.897119 0.000000 15.118110 0.000000
+ S 0 0.000000 0.000000 5.039370 2.220991 5.039370
+ S 0 0.000000 2.220991 5.039370 12.897119 5.039370
+ S 0 0.000000 12.897119 5.039370 15.118110 5.039370
+ C 0 0.000000 -6.425198 2.221000 6.425198 139.921630 40.078446
+ S 0 0.000000 6.357761 1.508868 8.760349 3.530502
+ C 0 0.000000 6.425198 12.897126 -1.385823 319.921630 40.078446
+ C 0 0.000000 6.425198 2.220966 -1.385828 0.000076 40.078446
+ S 0 0.000000 6.357761 3.530502 8.760349 1.508868
+ C 0 0.000000 -6.425198 12.897126 6.425193 180.000076 40.078446
+ END
diff --git a/app/lib/params/S-MTH S-Trax.xtp b/app/lib/params/S-MTH S-Trax.xtp
new file mode 100644
index 0000000..964c2a9
--- /dev/null
+++ b/app/lib/params/S-MTH S-Trax.xtp
@@ -0,0 +1,156 @@
+CONTENTS MTH S-Trax S Scale Track
+SUBCONTENTS MTH S-Trax S Scale Track - Straight Track
+TURNOUT S "MTH S-Trax 5"" Straight 35-1003"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 5.000000 0.000000 90.000000
+ S 0 0 0.000000 0.000000 5.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 5.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 5.000000 -1.281250
+END
+TURNOUT S "MTH S-Trax 10"" Straight 35-1002"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 10.000000 0.000000 90.000000
+ S 0 0 0.000000 0.000000 10.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 10.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 10.000000 -1.281250
+END
+TURNOUT S "MTH S-Trax 15"" Straight 35-1001"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 15.000000 0.000000 90.000000
+ S 0 0 0.000000 0.000000 15.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 15.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 15.000000 -1.281250
+END
+TURNOUT S "MTH S-Trax 40"" Flex Straight 35-1004/5"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 40.000000 0.000000 90.000000
+ S 0 0 0.000000 0.000000 40.000000 0.000000
+END
+
+SUBCONTENTS MTH S-Trax S Scale Track - Curve Track
+TURNOUT S "MTH S-Trax 20"" 30D Curve 35-1006"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 10.000000 -2.679492 120.000000
+ C 0 0 20.000000 0.000000 -20.000000 0.000000 30.000000
+ A 11579568 0.053333 21.281250 0.000000 -20.000000 0.000000 30.000000
+ A 11579568 0.053333 18.718750 0.000000 -20.000000 0.000000 30.000000
+END
+TURNOUT S "MTH S-Trax 20"" 15D Curve 35-1007"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 5.176381 -0.681483 105.000000
+ C 0 0 20.000000 0.000000 -20.000000 0.000000 15.000000
+ A 11579568 0.053333 21.281250 0.000000 -20.000000 0.000000 15.000000
+ A 11579568 0.053333 18.718750 0.000000 -20.000000 0.000000 15.000000
+END
+TURNOUT S "MTH S-Trax 25"" 30D Curve 35-1008"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 12.500000 -3.349365 120.000000
+ C 0 0 25.000000 0.000000 -25.000000 0.000000 30.000000
+ A 11579568 0.053333 26.281250 0.000000 -25.000000 0.000000 30.000000
+ A 11579568 0.053333 23.718750 0.000000 -25.000000 0.000000 30.000000
+END
+TURNOUT S "MTH S-Trax 25"" 15D Curve 35-1009"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 6.470476 -0.851854 105.000000
+ C 0 0 25.000000 0.000000 -25.000000 0.000000 15.000000
+ A 11579568 0.053333 26.281250 0.000000 -25.000000 0.000000 15.000000
+ A 11579568 0.053333 23.718750 0.000000 -25.000000 0.000000 15.000000
+END
+TURNOUT S "MTH S-Trax 30"" 30D Curve 35-1010"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 15.000000 -4.019238 120.000000
+ C 0 0 30.000000 0.000000 -30.000000 0.000000 30.000000
+ A 11579568 0.053333 31.281250 0.000000 -30.000000 0.000000 30.000000
+ A 11579568 0.053333 28.718750 0.000000 -30.000000 0.000000 30.000000
+END
+TURNOUT S "MTH S-Trax 30"" 15D Curve 35-1011"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 7.764571 -1.022225 105.000000
+ C 0 0 30.000000 0.000000 -30.000000 0.000000 15.000000
+ A 11579568 0.053333 31.281250 0.000000 -30.000000 0.000000 15.000000
+ A 11579568 0.053333 28.718750 0.000000 -30.000000 0.000000 15.000000
+END
+
+SUBCONTENTS MTH S-Trax S Scale Track - Misc Track
+TURNOUT S "MTH S-Trax 5"" Bumper 35-1021"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ S 0 0 0.000000 0.000000 5.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 6.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 6.000000 -1.281250
+ L 11579568 0.053333 6.000000 1.281250 6.000000 -1.281250
+ L 0 0.070000 4.000000 0.000000 5.000000 0.437000
+ L 0 0.070000 4.000000 0.000000 5.000000 -0.437000
+ L 0 0.070000 4.000000 0.437000 4.000000 -0.437000
+END
+TURNOUT S "MTH S-Trax 5"" Uncoupler 35-1022"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 5.000000 0.000000 90.000000
+ S 0 0 0.000000 0.000000 5.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 5.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 5.000000 -1.281250
+ L 11579568 0.053333 1.000000 0.000000 4.000000 0.000000
+ F 12566463 0.000000 4
+ 1.000000 0.250000 0
+ 1.500000 0.250000 0
+ 1.500000 -0.250000 0
+ 1.000000 -0.250000 0
+ F 12566463 0.000000 4
+ 3.500000 0.250000 0
+ 4.000000 0.250000 0
+ 4.000000 -0.250000 0
+ 3.500000 -0.250000 0
+END
+TURNOUT S "MTH S-Trax 5"" Acc. Operator 35-1023"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 5.000000 0.000000 90.000000
+ S 0 0 0.000000 0.000000 5.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 5.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 5.000000 -1.281250
+END
+
+SUBCONTENTS MTH S-Trax S Scale Track - Turnout
+TURNOUT S "MTH S-Trax #3 Left Turnout 35-1019"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 10.000000 0.000000 90.000000
+ E 10.000000 2.500000 60.000000
+ S 0 0.000000 0.000000 0.000000 1.543918 0.000000
+ S 0 0.000000 1.543918 0.000000 10.000000 0.000000
+ C 0 0.000000 -15.398371 1.543938 15.398371 149.999924 30.000152
+ S 0 0.000000 9.243132 2.063007 10.000000 2.500000
+ L 11579568 0.053333 -0.000003 -1.281250 9.999997 -1.281239
+ L 11579568 0.053333 0.000000 1.281250 1.543918 1.281252
+ A 11579568 0.053333 14.117121 1.543938 15.398371 149.999924 30.000152
+ L 11579568 0.053333 10.356817 1.226543 10.640643 1.390415
+ L 11579568 0.053333 8.602493 3.172594 9.359360 3.609587
+END
+TURNOUT S "MTH S-Trax #3 Right Turnout 35-1018"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 10.000000 0.000000 90.000000
+ E 10.000000 -2.500000 120.000000
+ S 0 0.000000 0.000000 0.000000 1.543918 0.000000
+ S 0 0.000000 1.543918 0.000000 10.000000 0.000000
+ C 0 0.000000 15.398371 1.543856 -15.398371 0.000076 30.000152
+ S 0 0.000000 9.243132 -2.063007 10.000000 -2.500000
+ L 11579568 0.053333 -0.000003 -1.281250 1.543914 -1.281248
+ L 11579568 0.053333 0.000000 1.281250 10.000000 1.281261
+ A 11579568 0.053333 14.117121 1.543856 -15.398371 0.000076 30.000152
+ L 11579568 0.053333 8.602487 -3.172591 9.359354 -3.609583
+ L 11579568 0.053333 10.356817 -1.226543 10.640643 -1.390415
+END \ No newline at end of file
diff --git a/app/lib/params/S-SHelper S-Trax.xtp b/app/lib/params/S-SHelper S-Trax.xtp
new file mode 100644
index 0000000..5be8270
--- /dev/null
+++ b/app/lib/params/S-SHelper S-Trax.xtp
@@ -0,0 +1,200 @@
+CONTENTS S Helper Showcase Line Code 131 S Scale
+SUBCONTENTS S Helper Showcase Line Code 131 - Straight Track
+TURNOUT S "S Helper Showcase Line C131 5"" Straight 297"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 5.000000 0.000000 90.000000
+ S 0 0 0.000000 0.000000 5.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 5.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 5.000000 -1.281250
+ END
+TURNOUT S "S Helper Showcase Line C131 10"" Straight 258"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 10.000000 0.000000 90.000000
+ S 0 0 0.000000 0.000000 10.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 10.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 10.000000 -1.281250
+ END
+TURNOUT S "S Helper Showcase Line C131 15"" Straight 257"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 15.000000 0.000000 90.000000
+ S 0 0 0.000000 0.000000 15.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 15.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 15.000000 -1.281250
+ END
+TURNOUT S "S Helper Showcase Line C131 36"" Straight 465"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 36.000000 0.000000 90.000000
+ S 0 0 0.000000 0.000000 36.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 36.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 36.000000 -1.281250
+ END
+
+SUBCONTENTS S Helper Showcase Line Code 131 - Curve Track
+TURNOUT S "S Helper Showcase Line C131 20"" 30D Curve 259"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 10.000000 -2.679492 120.000000
+ C 0 0 20.000000 0.000000 -20.000000 0.000000 30.000000
+ A 11579568 0.053333 21.281250 0.000000 -20.000000 0.000000 30.000000
+ A 11579568 0.053333 18.718750 0.000000 -20.000000 0.000000 30.000000
+ END
+TURNOUT S "S Helper Showcase Line C131 20"" 15D Curve 291"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 5.176381 -0.681483 105.000000
+ C 0 0 20.000000 0.000000 -20.000000 0.000000 15.000000
+ A 11579568 0.053333 21.281250 0.000000 -20.000000 0.000000 15.000000
+ A 11579568 0.053333 18.718750 0.000000 -20.000000 0.000000 15.000000
+ END
+TURNOUT S "S Helper Showcase Line C131 25"" 30D Curve 292"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 12.500000 -3.349365 120.000000
+ C 0 0 25.000000 0.000000 -25.000000 0.000000 30.000000
+ A 11579568 0.053333 26.281250 0.000000 -25.000000 0.000000 30.000000
+ A 11579568 0.053333 23.718750 0.000000 -25.000000 0.000000 30.000000
+ END
+TURNOUT S "S Helper Showcase Line C131 25"" 15D Curve 293"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 6.470476 -0.851854 105.000000
+ C 0 0 25.000000 0.000000 -25.000000 0.000000 15.000000
+ A 11579568 0.053333 26.281250 0.000000 -25.000000 0.000000 15.000000
+ A 11579568 0.053333 23.718750 0.000000 -25.000000 0.000000 15.000000
+ END
+TURNOUT S "S Helper Showcase Line C131 30"" 30D Curve 294"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 15.000000 -4.019238 120.000000
+ C 0 0 30.000000 0.000000 -30.000000 0.000000 30.000000
+ A 11579568 0.053333 31.281250 0.000000 -30.000000 0.000000 30.000000
+ A 11579568 0.053333 28.718750 0.000000 -30.000000 0.000000 30.000000
+ END
+TURNOUT S "S Helper Showcase Line C131 30"" 15D Curve 296"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 7.764571 -1.022225 105.000000
+ C 0 0 30.000000 0.000000 -30.000000 0.000000 15.000000
+ A 11579568 0.053333 31.281250 0.000000 -30.000000 0.000000 15.000000
+ A 11579568 0.053333 28.718750 0.000000 -30.000000 0.000000 15.000000
+ END
+
+
+SUBCONTENTS S Helper Showcase Line Code 131 - Crossings
+TURNOUT S "S Helper Showcase Line C131 5"" 90D Crossing 467"
+ P "Normal" 1 0 2
+ E 0.000000 0.000000 270.000000
+ E 5.000000 0.000000 90.000000
+ E 2.500000 2.500000 0.000000
+ E 2.500000 -2.500000 180.000000
+ S 0 0 0.000000 0.000000 5.000000 0.000000
+ S 0 0 2.500000 2.500000 2.500000 -2.500000
+ L 11579568 0.053333 0.000000 1.281250 1.218750 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 1.218750 -1.281250
+ L 11579568 0.053333 3.781250 1.281250 5.000000 1.281250
+ L 11579568 0.053333 3.781250 -1.281250 5.000000 -1.281250
+ L 11579568 0.053333 1.218750 2.500000 1.218750 1.281250
+ L 11579568 0.053333 3.781250 2.500000 3.781250 1.281250
+ L 11579568 0.053333 1.218750 -1.281250 1.218750 -2.500000
+ L 11579568 0.053333 3.781250 -1.281250 3.781250 -2.500000
+ END
+
+
+
+SUBCONTENTS S Helper Showcase Line Code 131 - Misc Track
+TURNOUT S "S Helper Showcase Line C131 5"" LED Bumper 468"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ S 0 0 0.000000 0.000000 4.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 5.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 5.000000 -1.281250
+ L 11579568 0.053333 5.000000 1.281250 5.000000 -1.281250
+ L 0 0.053333 3.126000 0.437000 4.000000 0.437000
+ L 0 0.053333 3.126000 -0.437000 4.000000 -0.437000
+ L 0 0.053333 4.000000 0.437000 4.000000 -0.437000
+ L 0 0.053333 3.126000 0.437000 3.126000 -0.437000
+ L 0 0.053333 3.126000 0.437000 4.000000 -0.437000
+ L 0 0.053333 3.126000 -0.437000 4.000000 0.437000
+ G 16711680 0.000000 0.150000 3.563000 0.000000 0
+ END
+TURNOUT S "S Helper Showcase Line C131 5"" Bumper 926"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ S 0 0 0.000000 0.000000 4.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 5.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 5.000000 -1.281250
+ L 11579568 0.053333 5.000000 1.281250 5.000000 -1.281250
+ L 0 0.053333 3.126000 0.437000 4.000000 0.437000
+ L 0 0.053333 3.126000 -0.437000 4.000000 -0.437000
+ L 0 0.053333 4.000000 0.437000 4.000000 -0.437000
+ L 0 0.053333 3.126000 0.437000 3.126000 -0.437000
+ L 0 0.053333 3.126000 0.437000 4.000000 -0.437000
+ L 0 0.053333 3.126000 -0.437000 4.000000 0.437000
+ END
+TURNOUT S "S Helper Showcase Line C131 5"" Uncoupler 670"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 5.000000 0.000000 90.000000
+ S 0 0 0.000000 0.000000 5.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 5.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 5.000000 -1.281250
+ L 11579568 0.053333 1.000000 0.000000 4.000000 0.000000
+ F 12566463 0.000000 4
+ 1.000000 0.250000 0
+ 1.500000 0.250000 0
+ 1.500000 -0.250000 0
+ 1.000000 -0.250000 0
+ F 12566463 0.000000 4
+ 3.500000 0.250000 0
+ 4.000000 0.250000 0
+ 4.000000 -0.250000 0
+ 3.500000 -0.250000 0
+ END
+TURNOUT S "S Helper Showcase Line C131 5"" Third Rail 671"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 5.000000 0.000000 90.000000
+ S 0 0 0.000000 0.000000 5.000000 0.000000
+ L 11579568 0.053333 0.000000 1.281250 5.000000 1.281250
+ L 11579568 0.053333 0.000000 -1.281250 5.000000 -1.281250
+ L 0 0.053333 0.000000 1.281250 5.000000 1.281250
+ END
+
+
+SUBCONTENTS S Helper Showcase Line Code 131 - Turnout
+TURNOUT S "S Helper Showcase Line #3 Left Turnout 299"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 10.000000 0.000000 90.000000
+ E 10.000000 2.500000 60.000000
+ S 0 0.000000 0.000000 0.000000 1.543918 0.000000
+ S 0 0.000000 1.543918 0.000000 10.000000 0.000000
+ C 0 0.000000 -15.398371 1.543938 15.398371 149.999924 30.000152
+ S 0 0.000000 9.243132 2.063007 10.000000 2.500000
+ L 11579568 0.053333 -0.000003 -1.281250 10.000000 -1.281239
+ L 11579568 0.053333 0.000000 1.281250 1.543918 1.281252
+ A 11579568 0.053333 14.117121 1.543938 15.398371 150.000000 30.000000
+ L 11579568 0.053333 10.356817 1.226543 10.640643 1.390415
+ L 11579568 0.053333 8.602493 3.172594 9.359360 3.609587
+ END
+TURNOUT S "S Helper Showcase Line #3 Right Turnout 298"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 10.000000 0.000000 90.000000
+ E 10.000000 -2.500000 120.000000
+ S 0 0.000000 0.000000 0.000000 1.543918 0.000000
+ S 0 0.000000 1.543918 0.000000 10.000000 0.000000
+ C 0 0.000000 15.398371 1.543856 -15.398371 0.000076 30.000152
+ S 0 0.000000 9.243132 -2.063007 10.000000 -2.500000
+ L 11579568 0.053333 -0.000003 -1.281250 1.543914 -1.281248
+ L 11579568 0.053333 0.000000 1.281250 10.000000 1.281261
+ A 11579568 0.053333 14.117121 1.543856 -15.398371 0.000000 30.000000
+ L 11579568 0.053333 8.602487 -3.172591 9.359354 -3.609583
+ L 11579568 0.053333 10.356817 -1.226543 10.640643 -1.390415
+END \ No newline at end of file
diff --git a/app/lib/params/TT-Kuehn.xtp b/app/lib/params/TT-Kuehn.xtp
index 12585a5..a71f195 100644
--- a/app/lib/params/TT-Kuehn.xtp
+++ b/app/lib/params/TT-Kuehn.xtp
@@ -56,16 +56,16 @@ TURNOUT TT "Kuehn Track R2 Curve 14.37R 365mm 10° 72210"
E 2.495338 -0.218314 100.000000
C 0 0 14.370079 0.000000 -14.370079 0.000000 10.000000
END
-TURNOUT TT "Kuehn Track R2 Curve 14.37R 353mm 20° 72220"
+TURNOUT TT "Kuehn Track R2 Curve 14.37R 365mm 20° 72220"
P "Normal" 1
E 0.000000 0.000000 270.000000
E 4.914856 -0.866622 110.000000
C 0 0 14.370079 0.000000 -14.370079 0.000000 20.000000
END
-TURNOUT TT "Kuehn Track R2 Curve 14.37R 353mm 30° 72230"
+TURNOUT TT "Kuehn Track R2 Curve 14.37R 365mm 30° 72230"
P "Normal" 1
E 0.000000 0.000000 270.000000
- E 7.1185039 -1.925225 120.000000
+ E 7.1850394 -1.925225 120.000000
C 0 0 14.370079 0.000000 -14.370079 0.000000 30.000000
END
diff --git a/app/lib/params/TTi-AuhagenNG.xtp b/app/lib/params/TTi-AuhagenNG.xtp
new file mode 100644
index 0000000..4dc194c
--- /dev/null
+++ b/app/lib/params/TTi-AuhagenNG.xtp
@@ -0,0 +1,40 @@
+CONTENTS Auhagen Narrow Gauge TT Scale Track System
+SUBCONTENTS Auhagen TTi Narrow Gauge Track - Straight Track
+TURNOUT TTi "Auhagen TTi Track G44 Straight 1.65 41.7mm 43700-1"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 1.641732 0.000000 90.000000
+ S 0 0 0.000000 0.000000 1.641732 0.000000
+ END
+
+SUBCONTENTS Auhagen TTi Narrow Gauge Track - Curve Track
+TURNOUT TTi "Auhagen TTi Track Curve 1.65R 42mm 30 43700-2"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 0.820866 -0.219950 120.000000
+ C 0 0 1.641732 0.000000 -1.641732 0.000000 30.000000
+ END
+
+SUBCONTENTS Auhagen TTi Narrow Gauge Track - Turnouts
+TURNOUT TTi "Auhagen TTi Track Left Turnout 43700-3"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 1.212598 0.000000 90.000000
+ E 1.212598 0.437530 60.000000
+ S 0 0.000000 0.000000 0.000000 0.177000 0.000000
+ S 0 0.000000 0.177000 0.000000 1.212598 0.000000
+ C 0 0.000000 -1.036677 0.177001 1.036677 149.999924 30.000152
+ S 0 0.000000 0.695340 0.138889 1.212598 0.437530
+ END
+TURNOUT TTi "Auhagen TTi Track Right Turnout 43700-4"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 1.212598 0.000000 90.000000
+ E 1.212598 -0.437530 120.000000
+ S 0 0.000000 0.000000 0.000000 0.177000 0.000000
+ S 0 0.000000 0.177000 0.000000 1.212598 0.000000
+ C 0 0.000000 1.036677 0.176996 -1.036677 0.000076 30.000152
+ S 0 0.000000 0.695340 -0.138889 1.212598 -0.437530
+ END
diff --git a/app/lib/params/TilligAdvTT.xtp b/app/lib/params/TilligAdvTT.xtp
index 20d085e..b9ddf8b 100644
--- a/app/lib/params/TilligAdvTT.xtp
+++ b/app/lib/params/TilligAdvTT.xtp
@@ -1,304 +1,323 @@
-CONTENTS Pilz/Tillig Advance Track System
-SUBCONTENTS Pilz/Tillig TT-Scale Advance Track - Straight Track
-TURNOUT TT "Pilz/Tillig Track G1 Straight 6.535 166mm 83101"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 6.535433 0.000000 90.000000
- S 0 0 0.000000 0.000000 6.535433 0.000000
- END
-TURNOUT TT "Pilz/Tillig Track G2 Straight 3.268 83mm 83102"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 3.267717 0.000000 90.000000
- S 0 0 0.000000 0.000000 3.267717 0.000000
- END
-TURNOUT TT "Pilz/Tillig Track G3 Straight 1.692 43mm 83105"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 1.692913 0.000000 90.000000
- S 0 0 0.000000 0.000000 1.692913 0.000000
- END
-TURNOUT TT "Pilz/Tillig Track G4 Straight 1.633 41.5mm 83103"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 1.633858 0.000000 90.000000
- S 0 0 0.000000 0.000000 1.633858 0.000000
- END
-TURNOUT TT "Pilz/Tillig Track G5 Straight 1.437 36.5mm 83104"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 1.437008 0.000000 90.000000
- S 0 0 0.000000 0.000000 1.437008 0.000000
- END
-TURNOUT TT "Pilz/Tillig Track Adapter Track 2.244 57mm 83132"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 2.244094 0.000000 90.000000
- S 0 0 0.000000 0.000000 2.244094 0.000000
- END
-
-SUBCONTENTS Pilz/Tillig TT-Scale Advance Track - Curve Track
-TURNOUT TT "Pilz/Tillig Track R01 Curve 10.51R 267mm 30 83116"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 5.255906 -1.408316 120.000000
- C 0 0 10.511811 0.000000 -10.511811 0.000000 30.000000
- END
-TURNOUT TT "Pilz/Tillig Track R04 Curve 10.51R 267mm 7.5 83115"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 1.372067 -0.089930 97.500000
- C 0 0 10.511811 0.000000 -10.511811 0.000000 7.500000
- END
-TURNOUT TT "Pilz/Tillig Track R11 Curve 12.20R 310mm 30 83109"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 6.102362 -1.635123 120.000000
- C 0 0 12.204724 0.000000 -12.204724 0.000000 30.000000
- END
-TURNOUT TT "Pilz/Tillig Track R12 Curve 12.20R 310mm 15 83110"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 3.158815 -0.415866 105.000000
- C 0 0 12.204724 0.000000 -12.204724 0.000000 15.000000
- END
-TURNOUT TT "Pilz/Tillig Track R14 Curve 12.20R 310mm 7.5 83113"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 1.593036 -0.104413 97.500000
- C 0 0 12.204724 0.000000 -12.204724 0.000000 7.500000
- END
-TURNOUT TT "Pilz/Tillig Track R21 Curve 13.89R 353mm 30 83106"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 6.948819 -1.861930 120.000000
- C 0 0 13.897638 0.000000 -13.897638 0.000000 30.000000
- END
-TURNOUT TT "Pilz/Tillig Track R22 Curve 13.89R 353mm 15 83107"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 3.596973 -0.473551 105.000000
- C 0 0 13.897638 0.000000 -13.897638 0.000000 15.000000
- END
-TURNOUT TT "Pilz/Tillig Track R24 Curve 13.89R 353mm 7.5 83114"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 1.814006 -0.118896 97.500000
- C 0 0 13.897638 0.000000 -13.897638 0.000000 7.500000
- END
-TURNOUT TT "Pilz/Tillig Track R31 Curve 15.59R 396mm 30 83111"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 7.795276 -2.088738 120.000000
- C 0 0 15.590551 0.000000 -15.590551 0.000000 30.000000
- END
-TURNOUT TT "Pilz/Tillig Track R32 Curve 15.59R 396mm 15 83112"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 4.035132 -0.531235 105.000000
- C 0 0 15.590551 0.000000 -15.590551 0.000000 15.000000
- END
-
-SUBCONTENTS Pilz/Tillig TT-Scale Advance Track - Function Track
-TURNOUT TT "Pilz/Tillig Track Straight Feeder 6.535 166mm 83149"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 6.535433 0.000000 90.000000
- S 0 0 0.000000 0.000000 6.535433 0.000000
- F 11579568 0.000000 4
- 0.500000 -0.500000 0
- 1.000000 -0.500000 0
- 1.000000 -1.000000 0
- 0.500000 -1.000000 0
- END
-TURNOUT TT "Pilz/Tillig Track Uncouple Track 3.268 83mm 83201"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 3.267717 0.000000 90.000000
- S 0 0 0.000000 0.000000 3.267717 0.000000
- F 11579568 0.000000 4
- 0.000000 -0.500000 0
- 2.750000 -0.500000 0
- 2.750000 -1.000000 0
- 0.000000 -1.000000 0
- F 11579568 0.000000 4
- 0.5000000 -0.200000 0
- 2.750000 -0.200000 0
- 2.750000 0.200000 0
- 0.500000 0.2000000 0
- END
-TURNOUT TT "Pilz/Tillig Track Isolation Track 1.633 41.5mm 83150"
- P "Normal" 1
- E 0.000000 0.000000 270.000000
- E 1.633858 0.000000 90.000000
- S 0 0 0.000000 0.000000 1.633858 0.000000
- END
-
-SUBCONTENTS Pilz/Tillig TT-Scale Advance Track - Turnouts
-TURNOUT TT "Tillig EW1-left 83322"
- P "Normal" 1
- P "Reverse" 2 3
- E 0.000000 0.000000 270.000000
- E 5.098425 0.000000 90.000000
- E 4.985016 0.845476 75.000000
- S 0 0.000000 0.000000 0.000000 5.098425 0.000000
- C 0 0.000000 -13.897638 0.000000 13.897638 165.000000 15.000000
- S 0 0.000000 3.596973 0.473551 4.985016 0.845476
- END
-TURNOUT TT "Tillig EW1-right 83321"
- P "Normal" 1
- P "Reverse" 2 3
- E 0.000000 0.000000 270.000000
- E 5.098425 0.000000 90.000000
- E 4.985016 -0.845476 105.000000
- S 0 0.000000 0.000000 0.000000 5.098425 0.000000
- C 0 0.000000 13.897638 0.000000 -13.897638 0.000000 15.000000
- S 0 0.000000 3.596973 -0.473551 4.985016 -0.845476
- END
-TURNOUT TT "Tillig EW2-left 83322"
- P "Normal" 1 2
- P "Reverse" 1 3 4
- E 0.000000 0.000000 270.000000
- E 6.535433 0.000000 90.000000
- E 6.429717 0.846488 75.000000
- S 0 0.000000 0.000000 0.000000 0.472063 0.000000
- S 0 0.000000 0.472063 0.000000 6.535433 0.000000
- C 0 0.000000 -21.257102 0.472091 21.257102 164.999924 15.000152
- S 0 0.000000 5.973856 0.724332 6.429717 0.846488
- END
-TURNOUT TT "Tillig EW2-right 83321"
- P "Normal" 1 2
- P "Reverse" 1 3 4
- E 0.000000 0.000000 270.000000
- E 6.535433 0.000000 90.000000
- E 6.429717 -0.846488 105.000000
- S 0 0.000000 0.000000 0.000000 0.472063 0.000000
- S 0 0.000000 0.472063 0.000000 6.535433 0.000000
- C 0 0.000000 21.257102 0.471978 -21.257102 0.000076 15.000152
- S 0 0.000000 5.973856 -0.724332 6.429717 -0.846488
- END
-TURNOUT TT "Tillig EW3-left 83342"
- P "Normal" 1 2
- P "Reverse" 1 3 4
- E 0.000000 0.000000 270.000000
- E 8.149606 0.000000 90.000000
- E 8.054532 0.846565 78.000000
- S 0 0.000000 0.000000 0.000000 0.472100 0.000000
- S 0 0.000000 0.472100 0.000000 8.149606 0.000000
- C 0 0.000000 -34.248932 0.472145 34.248932 167.999924 12.000152
- S 0 0.000000 7.592936 0.748439 8.054532 0.846565
- END
-TURNOUT TT "Tillig EW3-right 83341"
- P "Normal" 1 2
- P "Reverse" 1 3 4
- E 0.000000 0.000000 270.000000
- E 8.149606 0.000000 90.000000
- E 8.054532 -0.846565 102.000000
- S 0 0.000000 0.000000 0.000000 0.472100 0.000000
- S 0 0.000000 0.472100 0.000000 8.149606 0.000000
- C 0 0.000000 34.248932 0.471964 -34.248932 0.000076 12.000152
- S 0 0.000000 7.592936 -0.748439 8.054532 -0.846565
- END
-TURNOUT TT "Tillig IBW-left 83362"
- P "Normal" 1 4 5
- P "Reverse" 1 2 3
- E 0.000000 0.000000 270.000000
- E 6.429717 0.846488 75.000000
- E 6.102362 1.635123 60.000000
- S 0 0.000000 0.000000 0.000000 0.472027 0.000000
- C 0 0.000000 -10.443154 0.472041 10.443154 149.999924 30.000152
- S 0 0.000000 5.693624 1.399129 6.102362 1.635123
- C 0 0.000000 -21.257102 0.472091 21.257102 164.999924 15.000249
- S 0 0.000000 5.973856 0.724332 6.429717 0.846488
- END
-TURNOUT TT "Tillig IBW-right 83361"
- P "Normal" 1 4 5
- P "Reverse" 1 2 3
- E 0.000000 0.000000 270.000000
- E 6.429717 -0.846488 105.000000
- E 6.102362 -1.635123 120.000000
- S 0 0.000000 0.000000 0.000000 0.472027 0.000000
- C 0 0.000000 10.443154 0.471985 -10.443154 0.000076 30.000152
- S 0 0.000000 5.693624 -1.399129 6.102362 -1.635123
- C 0 0.000000 21.257102 0.472091 -21.257102 359.999979 15.000249
- S 0 0.000000 5.973856 -0.724332 6.429717 -0.846488
- END
-TURNOUT TT "Tillig ABW-15 Wye 83380"
- P "Left" 1 2 3
- P "Right" 1 4 5
- E 0.000000 0.000000 270.000000
- E 6.552004 0.429441 82.500000
- E 6.552004 -0.429441 97.500000
- S 0 0.000000 0.000000 0.000000 0.472128 0.000000
- C 0 0.000000 -42.994583 0.472185 42.994583 172.499924 7.500152
- S 0 0.000000 6.084156 0.367839 6.552004 0.429441
- C 0 0.000000 42.994583 0.471957 -42.994583 0.000076 7.500152
- S 0 0.000000 6.084156 -0.367839 6.552004 -0.429441
- END
-TURNOUT TT "Tillig ABW-12 Wye 83382"
- P "Left" 1 2 3
- P "Right" 1 4 5
- E 0.000000 0.000000 270.000000
- E 8.172974 0.428327 84.000000
- E 8.172974 -0.428327 96.000000
- S 0 0.000000 0.000000 0.000000 0.472209 0.000000
- C 0 0.000000 -69.180753 0.472300 69.180753 173.999924 6.000152
- S 0 0.000000 7.703743 0.378998 8.172974 0.428327
- C 0 0.000000 69.180753 0.471933 -69.180753 0.000076 6.000152
- S 0 0.000000 7.703743 -0.378998 8.172974 -0.428327
- END
-TURNOUT TT "Tillig DKW15 DOuble-Slip 83300"
- P "Normal" 1 2 3 0 4 5 6
- P "Reverse" 1 7 6 0 4 8 3
- E 0.000000 0.000000 270.000000
- E 6.535433 0.000000 90.000000
- E 0.111343 0.845742 285.000000
- E 6.424090 -0.845742 105.000000
- S 0 0.000000 0.000000 0.000000 0.944089 0.000000
- S 0 0.000000 0.944089 0.000000 5.591344 0.000000
- S 0 0.000000 5.591344 0.000000 6.535433 0.000000
- S 0 0.000000 0.111343 0.845742 1.023131 0.601422
- S 0 0.000000 1.023131 0.601422 5.512302 -0.601422
- S 0 0.000000 5.512302 -0.601422 6.424090 -0.845742
- C 0 0.000000 17.650057 0.944019 -17.650057 0.000076 15.000152
- C 0 0.000000 -17.650057 5.591366 17.650051 180.000076 15.000152
- END
-TURNOUT TT "Tillig DGV Dbl. Crossover 83210"
- P "Normal" 1 2 3 0 4 5 6
- P "Reverse" 1 7 8 9 6 0 4 10 11 12 3
- E 0.000000 0.000000 270.000000
- E 9.881890 0.000000 90.000000
- E 0.000000 1.692913 270.000000
- E 9.881890 1.692913 90.000000
- S 0 0.000000 0.000000 0.000000 0.789084 0.000000
- S 0 0.000000 0.789084 0.000000 9.092806 0.000000
- S 0 0.000000 9.092806 0.000000 9.881890 0.000000
- S 0 0.000000 0.000000 1.692913 0.789084 1.692913
- S 0 0.000000 0.789084 1.692913 9.092806 1.692913
- S 0 0.000000 9.092806 1.692913 9.881890 1.692913
- C 0 0.000000 -10.474132 0.789097 10.474132 159.252360 20.747716
- S 0 0.000000 4.499581 0.679253 5.382309 1.013660
- C 0 0.000000 10.474132 9.092819 -8.781214 339.252360 20.747716
- C 0 0.000000 10.474132 0.789042 -8.781219 0.000076 20.747716
- S 0 0.000000 4.499581 1.013660 5.382309 0.679253
- C 0 0.000000 -10.474132 9.092819 10.474127 180.000076 20.747716
- END
-SUBCONTENTS Pilz/Tillig TT-Scale Advance Track - Crossings
-TURNOUT TT "Tillig K1-15 Crossing 83160"
- P "Normal" 1 0 2
- E 0.000000 0.000000 270.000000
- E 6.535433 0.000000 90.000000
- E 0.111343 0.845742 285.000000
- E 6.424090 -0.845742 105.000000
- S 0 0.000000 0.000000 0.000000 6.535433 0.000000
- S 0 0.000000 0.111343 0.845742 6.424090 -0.845742
- END
-TURNOUT TT "Tillig K2-30 Crossing 83170"
- P "Normal" 1 0 2
- E 0.000000 0.000000 270.000000
- E 3.267717 0.000000 90.000000
- E 0.218894 0.816927 300.000000
- E 3.048823 -0.816927 120.000000
- S 0 0.000000 0.000000 0.000000 3.267717 0.000000
- S 0 0.000000 0.218894 0.816927 3.048823 -0.816927
- END
+CONTENTS Pilz/Tillig Advance Track System
+SUBCONTENTS Pilz/Tillig TT-Scale Advance Track - Straight Track
+TURNOUT TT "Pilz/Tillig Track G1 Straight 6.535 166mm 83101"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 6.535433 0.000000 90.000000
+ S 0 0 0.000000 0.000000 6.535433 0.000000
+ END
+TURNOUT TT "Pilz/Tillig Track G2 Straight 3.268 83mm 83102"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 3.267717 0.000000 90.000000
+ S 0 0 0.000000 0.000000 3.267717 0.000000
+ END
+TURNOUT TT "Pilz/Tillig Track G3 Straight 1.692 43mm 83105"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 1.692913 0.000000 90.000000
+ S 0 0 0.000000 0.000000 1.692913 0.000000
+ END
+TURNOUT TT "Pilz/Tillig Track G4 Straight 1.633 41.5mm 83103"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 1.633858 0.000000 90.000000
+ S 0 0 0.000000 0.000000 1.633858 0.000000
+ END
+TURNOUT TT "Pilz/Tillig Track G5 Straight 1.437 36.5mm 83104"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 1.437008 0.000000 90.000000
+ S 0 0 0.000000 0.000000 1.437008 0.000000
+ END
+TURNOUT TT "Pilz/Tillig Track Adapter Track 2.244 57mm 83132"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 2.244094 0.000000 90.000000
+ S 0 0 0.000000 0.000000 2.244094 0.000000
+ END
+
+SUBCONTENTS Pilz/Tillig TT-Scale Advance Track - Curve Track
+TURNOUT TT "Pilz/Tillig Track R01 Curve 10.51R 267mm 30 83116"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 5.255906 -1.408316 120.000000
+ C 0 0 10.511811 0.000000 -10.511811 0.000000 30.000000
+ END
+TURNOUT TT "Pilz/Tillig Track R04 Curve 10.51R 267mm 7.5 83115"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 1.372067 -0.089930 97.500000
+ C 0 0 10.511811 0.000000 -10.511811 0.000000 7.500000
+ END
+TURNOUT TT "Pilz/Tillig Track R11 Curve 12.20R 310mm 30 83109"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 6.102362 -1.635123 120.000000
+ C 0 0 12.204724 0.000000 -12.204724 0.000000 30.000000
+ END
+TURNOUT TT "Pilz/Tillig Track R12 Curve 12.20R 310mm 15 83110"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 3.158815 -0.415866 105.000000
+ C 0 0 12.204724 0.000000 -12.204724 0.000000 15.000000
+ END
+TURNOUT TT "Pilz/Tillig Track R14 Curve 12.20R 310mm 7.5 83113"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 1.593036 -0.104413 97.500000
+ C 0 0 12.204724 0.000000 -12.204724 0.000000 7.500000
+ END
+TURNOUT TT "Pilz/Tillig Track R21 Curve 13.89R 353mm 30 83106"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 6.948819 -1.861930 120.000000
+ C 0 0 13.897638 0.000000 -13.897638 0.000000 30.000000
+ END
+TURNOUT TT "Pilz/Tillig Track R22 Curve 13.89R 353mm 15 83107"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 3.596973 -0.473551 105.000000
+ C 0 0 13.897638 0.000000 -13.897638 0.000000 15.000000
+ END
+TURNOUT TT "Pilz/Tillig Track R24 Curve 13.89R 353mm 7.5 83114"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 1.814006 -0.118896 97.500000
+ C 0 0 13.897638 0.000000 -13.897638 0.000000 7.500000
+ END
+TURNOUT TT "Pilz/Tillig Track R31 Curve 15.59R 396mm 30 83111"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 7.795276 -2.088738 120.000000
+ C 0 0 15.590551 0.000000 -15.590551 0.000000 30.000000
+ END
+TURNOUT TT "Pilz/Tillig Track R32 Curve 15.59R 396mm 15 83112"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 4.035132 -0.531235 105.000000
+ C 0 0 15.590551 0.000000 -15.590551 0.000000 15.000000
+ END
+
+SUBCONTENTS Pilz/Tillig TT-Scale Advance Track - Function Track
+TURNOUT TT "Pilz/Tillig Track Straight Feeder 6.535 166mm 83149"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 6.535433 0.000000 90.000000
+ S 0 0 0.000000 0.000000 6.535433 0.000000
+ F 11579568 0.000000 4
+ 0.500000 -0.500000 0
+ 1.000000 -0.500000 0
+ 1.000000 -1.000000 0
+ 0.500000 -1.000000 0
+ END
+TURNOUT TT "Pilz/Tillig Track Uncouple Track 3.268 83mm 83201"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 3.267717 0.000000 90.000000
+ S 0 0 0.000000 0.000000 3.267717 0.000000
+ F 11579568 0.000000 4
+ 0.000000 -0.500000 0
+ 2.750000 -0.500000 0
+ 2.750000 -1.000000 0
+ 0.000000 -1.000000 0
+ F 11579568 0.000000 4
+ 0.5000000 -0.200000 0
+ 2.750000 -0.200000 0
+ 2.750000 0.200000 0
+ 0.500000 0.2000000 0
+ END
+TURNOUT TT "Pilz/Tillig Track Isolation Track 1.633 41.5mm 83150"
+ P "Normal" 1
+ E 0.000000 0.000000 270.000000
+ E 1.633858 0.000000 90.000000
+ S 0 0 0.000000 0.000000 1.633858 0.000000
+ END
+
+SUBCONTENTS Pilz/Tillig TT-Scale Advance Track - Turnouts
+TURNOUT TT "Tillig EW1-left 15d 83322/27"
+ P "Normal" 1
+ P "Reverse" 2 3
+ E 0.000000 0.000000 270.000000
+ E 5.098425 0.000000 90.000000
+ E 4.985016 0.845476 75.000000
+ S 0 0.000000 0.000000 0.000000 5.098425 0.000000
+ C 0 0.000000 -13.897638 0.000000 13.897638 165.000000 15.000000
+ S 0 0.000000 3.596973 0.473551 4.985016 0.845476
+ END
+TURNOUT TT "Tillig EW1-right 15d 83321/26"
+ P "Normal" 1
+ P "Reverse" 2 3
+ E 0.000000 0.000000 270.000000
+ E 5.098425 0.000000 90.000000
+ E 4.985016 -0.845476 105.000000
+ S 0 0.000000 0.000000 0.000000 5.098425 0.000000
+ C 0 0.000000 13.897638 0.000000 -13.897638 0.000000 15.000000
+ S 0 0.000000 3.596973 -0.473551 4.985016 -0.845476
+ END
+TURNOUT TT "Tillig EW2-left 15d 83332"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 6.535433 0.000000 90.000000
+ E 6.429717 0.846488 75.000000
+ S 0 0.000000 0.000000 0.000000 0.472063 0.000000
+ S 0 0.000000 0.472063 0.000000 6.535433 0.000000
+ C 0 0.000000 -21.257102 0.472091 21.257102 164.999924 15.000152
+ S 0 0.000000 5.973856 0.724332 6.429717 0.846488
+ END
+TURNOUT TT "Tillig EW2-right 15d 83331"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 6.535433 0.000000 90.000000
+ E 6.429717 -0.846488 105.000000
+ S 0 0.000000 0.000000 0.000000 0.472063 0.000000
+ S 0 0.000000 0.472063 0.000000 6.535433 0.000000
+ C 0 0.000000 21.257102 0.471978 -21.257102 0.000076 15.000152
+ S 0 0.000000 5.973856 -0.724332 6.429717 -0.846488
+ END
+TURNOUT TT "Tillig EW3-left 12d 83342"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 8.149606 0.000000 90.000000
+ E 8.054532 0.846565 78.000000
+ S 0 0.000000 0.000000 0.000000 0.472100 0.000000
+ S 0 0.000000 0.472100 0.000000 8.149606 0.000000
+ C 0 0.000000 -34.248932 0.472145 34.248932 167.999924 12.000152
+ S 0 0.000000 7.592936 0.748439 8.054532 0.846565
+ END
+TURNOUT TT "Tillig EW3-right 12d 83341"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 8.149606 0.000000 90.000000
+ E 8.054532 -0.846565 102.000000
+ S 0 0.000000 0.000000 0.000000 0.472100 0.000000
+ S 0 0.000000 0.472100 0.000000 8.149606 0.000000
+ C 0 0.000000 34.248932 0.471964 -34.248932 0.000076 12.000152
+ S 0 0.000000 7.592936 -0.748439 8.054532 -0.846565
+ END
+TURNOUT TT "Tillig IBW-left 83362"
+ P "Normal" 1 4 5
+ P "Reverse" 1 2 3
+ E 0.000000 0.000000 270.000000
+ E 6.429717 0.846488 75.000000
+ E 6.102362 1.635123 60.000000
+ S 0 0.000000 0.000000 0.000000 0.472027 0.000000
+ C 0 0.000000 -10.443154 0.472041 10.443154 149.999924 30.000152
+ S 0 0.000000 5.693624 1.399129 6.102362 1.635123
+ C 0 0.000000 -21.257102 0.472091 21.257102 164.999924 15.000249
+ S 0 0.000000 5.973856 0.724332 6.429717 0.846488
+ END
+TURNOUT TT "Tillig IBW-right 83361"
+ P "Normal" 1 4 5
+ P "Reverse" 1 2 3
+ E 0.000000 0.000000 270.000000
+ E 6.429717 -0.846488 105.000000
+ E 6.102362 -1.635123 120.000000
+ S 0 0.000000 0.000000 0.000000 0.472027 0.000000
+ C 0 0.000000 10.443154 0.471985 -10.443154 0.000076 30.000152
+ S 0 0.000000 5.693624 -1.399129 6.102362 -1.635123
+ C 0 0.000000 21.257102 0.472091 -21.257102 359.999979 15.000249
+ S 0 0.000000 5.973856 -0.724332 6.429717 -0.846488
+ END
+SUBCONTENTS Pilz/Tillig TT-Scale Advance Track - Wyes
+TURNOUT TT "Tillig ABW-15 Wye 83380"
+ P "Left" 1 2 3
+ P "Right" 1 4 5
+ E 0.000000 0.000000 270.000000
+ E 6.552004 0.429441 82.500000
+ E 6.552004 -0.429441 97.500000
+ S 0 0.000000 0.000000 0.000000 0.472128 0.000000
+ C 0 0.000000 -42.994583 0.472185 42.994583 172.499924 7.500152
+ S 0 0.000000 6.084156 0.367839 6.552004 0.429441
+ C 0 0.000000 42.994583 0.471957 -42.994583 0.000076 7.500152
+ S 0 0.000000 6.084156 -0.367839 6.552004 -0.429441
+END
+TURNOUT TT "Tillig ABW-12 Wye 83382"
+ P "Left" 1 2 3
+ P "Right" 1 4 5
+ E 0.000000 0.000000 270.000000
+ E 8.172974 0.428327 84.000000
+ E 8.172974 -0.428327 96.000000
+ S 0 0.000000 0.000000 0.000000 0.472209 0.000000
+ C 0 0.000000 -69.180753 0.472300 69.180753 173.999924 6.000152
+ S 0 0.000000 7.703743 0.378998 8.172974 0.428327
+ C 0 0.000000 69.180753 0.471933 -69.180753 0.000076 6.000152
+ S 0 0.000000 7.703743 -0.378998 8.172974 -0.428327
+END
+TURNOUT TT "Tillig DW-15 Asymmetrical 3-Way 83230"
+ P "Normal" 1 2 3
+ P "Right" 1 4 5
+ P "Left" 1 2 6 7
+ E 0.000000 0.000000 270.000000
+ E 6.535433 0.000000 90.000000
+ E 6.429717 0.846488 75.000000
+ E 6.429717 -0.846488 105.000000
+ S 0 0.000000 0.000000 0.000000 0.472063 0.000000
+ S 0 0.000000 0.472063 0.000000 0.964945 0.000000
+ S 0 0.000000 0.964945 0.000000 6.535433 0.000000
+ C 0 0.000000 -21.257102 0.472091 21.257102 165.000000 15.000000
+ S 0 0.000000 5.973856 0.724332 6.429717 0.846488
+ C 0 0.000000 21.257102 0.964945 -21.257102 0.000000 15.000000
+ S 0 0.000000 6.938801 -0.724332 7.394662 -0.846488
+END
+SUBCONTENTS Pilz/Tillig TT-Scale Advance Track - Slips
+TURNOUT TT "Tillig DKW15 Double-Slip 83300/391"
+ P "Normal" 1 2 3 0 4 5 6
+ P "Reverse" 1 7 6 0 4 8 3
+ E 0.000000 0.000000 270.000000
+ E 6.535433 0.000000 90.000000
+ E 0.111343 0.845742 285.000000
+ E 6.424090 -0.845742 105.000000
+ S 0 0.000000 0.000000 0.000000 0.944089 0.000000
+ S 0 0.000000 0.944089 0.000000 5.591344 0.000000
+ S 0 0.000000 5.591344 0.000000 6.535433 0.000000
+ S 0 0.000000 0.111343 0.845742 1.023131 0.601422
+ S 0 0.000000 1.023131 0.601422 5.512302 -0.601422
+ S 0 0.000000 5.512302 -0.601422 6.424090 -0.845742
+ C 0 0.000000 17.650057 0.944019 -17.650057 0.000076 15.000152
+ C 0 0.000000 -17.650057 5.591366 17.650051 180.000076 15.000152
+END
+SUBCONTENTS Pilz/Tillig TT-Scale Advance Track - Double Crossover
+TURNOUT TT "Tillig DGV Dbl. Crossover 83210"
+ P "Normal" 1 2 3 0 4 5 6
+ P "Reverse" 1 7 8 9 6 0 4 10 11 12 3
+ E 0.000000 0.000000 270.000000
+ E 9.881890 0.000000 90.000000
+ E 0.000000 1.692913 270.000000
+ E 9.881890 1.692913 90.000000
+ S 0 0.000000 0.000000 0.000000 0.789084 0.000000
+ S 0 0.000000 0.789084 0.000000 9.092806 0.000000
+ S 0 0.000000 9.092806 0.000000 9.881890 0.000000
+ S 0 0.000000 0.000000 1.692913 0.789084 1.692913
+ S 0 0.000000 0.789084 1.692913 9.092806 1.692913
+ S 0 0.000000 9.092806 1.692913 9.881890 1.692913
+ C 0 0.000000 -10.474132 0.789097 10.474132 159.252360 20.747716
+ S 0 0.000000 4.499581 0.679253 5.382309 1.013660
+ C 0 0.000000 10.474132 9.092819 -8.781214 339.252360 20.747716
+ C 0 0.000000 10.474132 0.789042 -8.781219 0.000076 20.747716
+ S 0 0.000000 4.499581 1.013660 5.382309 0.679253
+ C 0 0.000000 -10.474132 9.092819 10.474127 180.000076 20.747716
+END
+SUBCONTENTS Pilz/Tillig TT-Scale Advance Track - Crossings
+TURNOUT TT "Tillig K1-15 Crossing 83160"
+ P "Normal" 1 0 2
+ E 0.000000 0.000000 270.000000
+ E 6.535433 0.000000 90.000000
+ E 0.111343 0.845742 285.000000
+ E 6.424090 -0.845742 105.000000
+ S 0 0.000000 0.000000 0.000000 6.535433 0.000000
+ S 0 0.000000 0.111343 0.845742 6.424090 -0.845742
+END
+TURNOUT TT "Tillig K2-30 Crossing 83170"
+ P "Normal" 1 0 2
+ E 0.000000 0.000000 270.000000
+ E 3.267717 0.000000 90.000000
+ E 0.218894 0.816927 300.000000
+ E 3.048823 -0.816927 120.000000
+ S 0 0.000000 0.000000 0.000000 3.267717 0.000000
+ S 0 0.000000 0.218894 0.816927 3.048823 -0.816927
+END
diff --git a/app/lib/params/atl83ho.xtp b/app/lib/params/atl83ho.xtp
index 4ce2387..d3271f4 100644
--- a/app/lib/params/atl83ho.xtp
+++ b/app/lib/params/atl83ho.xtp
@@ -385,7 +385,7 @@ TURNOUT HO "Atlas C83 Bumper 518"
S 0 0 0.000000 0.000000 3.750000 0.000000
END
-TURNOUT HO "Atlas C83 9" Warren Truss Bridge 590"
+TURNOUT HO "Atlas C83 9"" Warren Truss Bridge 590"
P "Normal" 1
E 0.000000 0.000000 270.000000
E 9.000000 0.000000 90.000000
@@ -397,7 +397,7 @@ TURNOUT HO "Atlas C83 9" Warren Truss Bridge 590"
L 11579568 0.050000 0.000000 -0.750000 0.000000 -1.200000
L 11579568 0.050000 9.000000 -0.750000 9.000000 -1.200000
END
-TURNOUT HO "Atlas C83 9" Deck Truss Bridge 591"
+TURNOUT HO "Atlas C83 9"" Deck Truss Bridge 591"
P "Normal" 1
E 0.000000 0.000000 270.000000
E 9.000000 0.000000 90.000000
@@ -409,7 +409,7 @@ TURNOUT HO "Atlas C83 9" Deck Truss Bridge 591"
L 11579568 0.050000 0.000000 -0.600000 0.000000 -0.700000
L 11579568 0.050000 9.000000 -0.600000 9.000000 -0.700000
END
-TURNOUT HO "Atlas C83 9" Plate Girder Bridge 592"
+TURNOUT HO "Atlas C83 9"" Plate Girder Bridge 592"
P "Normal" 1
E 0.000000 0.000000 270.000000
E 9.000000 0.000000 90.000000
@@ -421,7 +421,7 @@ TURNOUT HO "Atlas C83 9" Plate Girder Bridge 592"
L 11579568 0.050000 0.000000 -0.750000 0.000000 -1.300000
L 11579568 0.050000 9.000000 -0.750000 9.000000 -1.300000
END
-TURNOUT HO "Atlas C83 18" Through Truss Bridge 593/594"
+TURNOUT HO "Atlas C83 18"" Through Truss Bridge 593/594"
P "Normal" 1
E 0.000000 0.000000 270.000000
E 18.000000 0.000000 90.000000
diff --git a/app/lib/params/pecoho83.xtp b/app/lib/params/pecoho83.xtp
index 727ecaf..7af3cc2 100644
--- a/app/lib/params/pecoho83.xtp
+++ b/app/lib/params/pecoho83.xtp
@@ -1,126 +1,145 @@
-CONTENTS Peco North American Code 83 HO Scale Turnouts
-SUBCONTENTS Peco Code 83 HO Turnouts
-TURNOUT HO "PECO Code 83 #5 Left Hand Turnout SL-8352/SLE-8352"
- P "Normal" 1 2
- P "Reverse" 1 3 4
- E 0.000000 0.000000 270.000000
- E 8.307087 0.000000 90.000000
- E 8.307087 1.019252 78.463031
- S 0 0.000000 0.000000 0.000000 0.649600 0.000000
- S 0 0.000000 0.649600 0.000000 8.307087 0.000000
- C 0 0.000000 -26.373333 0.649635 26.373333 168.462955 11.537121
- S 0 0.000000 5.924335 0.532864 8.307087 1.019252
- END
-TURNOUT HO "PECO Code 83 #5 Right Hand Turnout SL-8351/SLE-8351"
- P "Normal" 1 2
- P "Reverse" 1 3 4
- E 0.000000 0.000000 270.000000
- E 8.307087 0.000000 90.000000
- E 8.307087 -1.019252 101.536969
- S 0 0.000000 0.000000 0.000000 0.649600 0.000000
- S 0 0.000000 0.649600 0.000000 8.307087 0.000000
- C 0 0.000000 26.373333 0.649495 -26.373333 0.000076 11.537121
- S 0 0.000000 5.924335 -0.532864 8.307087 -1.019252
- END
-TURNOUT HO "PECO Code 83 #6 Left Hand Turnout SL-8362/SLE-8362"
- P "Normal" 1 2
- P "Reverse" 1 3 4
- E 0.000000 0.000000 270.000000
- E 9.173228 0.000000 90.000000
- E 9.173228 1.023622 77.000000
- S 0 0.000000 0.000000 0.000000 0.838713 0.000000
- S 0 0.000000 0.838713 0.000000 9.173228 0.000000
- C 0 0.000000 -34.236656 0.838759 34.236656 166.999924 13.000152
- S 0 0.000000 8.540367 0.877502 9.173228 1.023622
- END
-TURNOUT HO "PECO Code 83 #6 Right Hand Turnout SL-8361/SLE-8361"
- P "Normal" 1 2
- P "Reverse" 1 3 4
- E 0.000000 0.000000 270.000000
- E 9.173228 0.000000 90.000000
- E 9.173228 -1.023622 103.000000
- S 0 0.000000 0.000000 0.000000 0.838713 0.000000
- S 0 0.000000 0.838713 0.000000 9.173228 0.000000
- C 0 0.000000 34.236656 0.838577 -34.236656 0.000076 13.000152
- S 0 0.000000 8.540367 -0.877502 9.173228 -1.023622
- END
-TURNOUT HO "PECO Code 83 #8 Left Hand Turnout SL-8382/SLE-8382"
- P "Normal" 1 2
- P "Reverse" 1 3 4
- E 0.000000 0.000000 270.000000
- E 12.677165 0.000000 90.000000
- E 12.677165 1.019213 82.819238
- S 0 0.000000 0.000000 0.000000 0.649600 0.000000
- S 0 0.000000 0.649600 0.000000 12.677165 0.000000
- C 0 0.000000 -62.760069 0.649683 62.760069 172.819162 7.180914
- S 0 0.000000 8.494774 0.492264 12.677165 1.019213
- END
-TURNOUT HO "PECO Code 83 #8 Right Hand Turnout SL-8381/SLE-8381"
- P "Normal" 1 2
- P "Reverse" 1 3 4
- E 0.000000 0.000000 270.000000
- E 12.677165 0.000000 90.000000
- E 12.677165 -1.019213 97.180762
- S 0 0.000000 0.000000 0.000000 0.649600 0.000000
- S 0 0.000000 0.649600 0.000000 12.677165 0.000000
- C 0 0.000000 62.760069 0.649350 -62.760069 0.000076 7.180914
- S 0 0.000000 8.494774 -0.492264 12.677165 -1.019213
- END
-TURNOUT HO "PECO Code 83 #4 WYE Turnout SL-8348/SLE-8348"
- P "Left" 1 2 3
- P "Right" 1 4 5
- E 0.000000 0.000000 270.000000
- E 7.159055 0.500000 82.850000
- E 7.159055 -0.500000 97.150000
- S 0 0.000000 0.000000 0.000000 0.649600 0.000000
- C 0 0.000000 -40.393551 0.649654 40.393551 172.849924 7.150152
- S 0 0.000000 5.677382 0.314125 7.159055 0.500000
- C 0 0.000000 40.393551 0.649439 -40.393551 0.000076 7.150152
- S 0 0.000000 5.677382 -0.314125 7.159055 -0.500000
- END
-
-SUBCONTENTS Peco Code 83 HO Crossings
-TURNOUT HO "PECO Code 83 #6 Diamond Crossing SL-8364/SLE-8364"
- P "Normal" 1 0 2
- E 0.000000 0.000000 270.000000
- E 12.035433 0.000000 90.000000
- E 0.084167 1.002945 279.594076
- E 11.951266 -1.002945 99.594076
- S 0 0.000000 0.000000 0.000000 12.035433 0.000000
- S 0 0.000000 0.084167 1.002945 11.951266 -1.002945
- END
-TURNOUT HO "PECO Code 83 90d Crossing SL-8390"
- P "Normal" 1 0 2
- E 0.000000 0.000000 270.000000
- E 2.000000 0.000000 90.000000
- E 1.000000 -1.000000 180.000000
- E 1.000000 1.000000 0.000000
- S 0 0.000000 0.000000 0.000000 2.000000 0.000000
- S 0 0.000000 1.000000 1.000000 1.000000 -1.000000
- END
-
-SUBCONTENTS Peco Code 83 HO Curved Turnouts
-TURNOUT HO "Peco Code 83 #7 Curved Left Turnout SL-8377/SLE-8377"
- P "Normal" 1 4 5
- P "Reverse" 1 2 3
- E 0.000000 0.000000 270.000000
- E 11.106693 0.984252 81.000000
- E 10.865748 1.968504 72.000000
- S 0 0.000000 0.000000 0.000000 0.649600 0.000000
- C 0 0.000000 -26.251070 0.649635 26.251070 161.999924 18.000152
- S 0 0.000000 8.761686 1.284838 10.865748 1.968504
- C 0 0.000000 -53.910688 0.649672 53.910688 170.999924 9.000152
- S 0 0.000000 9.083224 0.663751 11.106693 0.984252
- END
-TURNOUT HO "Peco Code 83 #7 Curved Right Turnout SL-8376/SLE-8376"
- P "Normal" 1 4 5
- P "Reverse" 1 2 3
- E 0.000000 0.000000 270.000000
- E 11.106693 -0.984252 99.000000
- E 10.865748 -1.968504 108.000000
- S 0 0.000000 0.000000 0.000000 0.649600 0.000000
- C 0 0.000000 26.251070 0.649496 -26.251070 0.000076 18.000152
- S 0 0.000000 8.761686 -1.284838 10.865748 -1.968504
- C 0 0.000000 53.910688 0.649385 -53.910688 0.000076 9.000152
- S 0 0.000000 9.083224 -0.663751 11.106693 -0.984252
- END
+CONTENTS Peco North American Code 83 HO Scale Turnouts
+#Updated based on PECO Website and PDF's
+SUBCONTENTS Peco Code 83 HO Turnouts
+TURNOUT HO "PECO Code 83 #5 Left Hand Turnout SL-8352/SLE-8352"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 8.259842 0.000000 90.000000
+ E 8.259842 1.000000 78.600000
+ S 0 0.000000 0.000000 0.000000 0.649600 0.000000
+ S 0 0.000000 0.649600 0.000000 8.259842 0.000000
+ C 0 0.000000 -26.558075 0.649635 26.558075 168.599924 11.400152
+ S 0 0.000000 5.899063 0.523973 8.259842 1.000000
+ END
+TURNOUT HO "PECO Code 83 #5 Right Hand Turnout SL-8351/SLE-8351"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 8.259842 0.000000 90.000000
+ E 8.259842 -1.000000 101.400000
+ S 0 0.000000 0.000000 0.000000 0.649600 0.000000
+ S 0 0.000000 0.649600 0.000000 8.259842 0.000000
+ C 0 0.000000 26.558075 0.649494 -26.558075 0.000076 11.400152
+ S 0 0.000000 5.899063 -0.523973 8.259842 -1.000000
+ END
+TURNOUT HO "PECO Code 83 #6 Left Hand Turnout SL-8362/SLE-8362"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 9.192913 0.000000 90.000000
+ E 9.192913 1.000000 80.500000
+ S 0 0.000000 0.000000 0.000000 0.649600 0.000000
+ S 0 0.000000 0.649600 0.000000 9.192913 0.000000
+ C 0 0.000000 -30.900336 0.649641 30.900336 170.499924 9.500152
+ S 0 0.000000 5.749703 0.423792 9.192913 1.000000
+ END
+TURNOUT HO "PECO Code 83 #6 Right Hand Turnout SL-8361/SLE-8361"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 9.192913 0.000000 90.000000
+ E 9.192913 -1.000000 99.500000
+ S 0 0.000000 0.000000 0.000000 0.649600 0.000000
+ S 0 0.000000 0.649600 0.000000 9.192913 0.000000
+ C 0 0.000000 30.900336 0.649477 -30.900336 0.000076 9.500152
+ S 0 0.000000 5.749703 -0.423792 9.192913 -1.000000
+ END
+TURNOUT HO "PECO Code 83 #8 Left Hand Turnout SL-8382/SLE-8382"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 12.649606 0.000000 90.000000
+ E 12.649606 1.000000 82.850000
+ S 0 0.000000 0.000000 0.000000 0.649600 0.000000
+ S 0 0.000000 0.649600 0.000000 12.649606 0.000000
+ C 0 0.000000 -64.478236 0.649686 64.478236 172.849924 7.150152
+ S 0 0.000000 8.675202 0.501423 12.649606 1.000000
+ END
+TURNOUT HO "PECO Code 83 #8 Right Hand Turnout SL-8381/SLE-8381"
+ P "Normal" 1 2
+ P "Reverse" 1 3 4
+ E 0.000000 0.000000 270.000000
+ E 12.649606 0.000000 90.000000
+ E 12.649606 -1.000000 97.150000
+ S 0 0.000000 0.000000 0.000000 0.649600 0.000000
+ S 0 0.000000 0.649600 0.000000 12.649606 0.000000
+ C 0 0.000000 64.478236 0.649343 -64.478236 0.000076 7.150152
+ S 0 0.000000 8.675202 -0.501423 12.649606 -1.000000
+ END
+SUBCONTENTS Peco Code 83 HO Wye Turnouts
+TURNOUT HO "PECO Code 83 #4 WYE Turnout SL-8348/SLE-8348"
+ P "Left" 1 2 3
+ P "Right" 1 4 5
+ E 0.000000 0.000000 270.000000
+ E 7.159055 0.500000 82.850000
+ E 7.159055 -0.500000 97.150000
+ S 0 0.000000 0.000000 0.000000 0.649600 0.000000
+ C 0 0.000000 -40.393551 0.649654 40.393551 172.849924 7.150152
+ S 0 0.000000 5.677382 0.314125 7.159055 0.500000
+ C 0 0.000000 40.393551 0.649439 -40.393551 0.000076 7.150152
+ S 0 0.000000 5.677382 -0.314125 7.159055 -0.500000
+ END
+
+SUBCONTENTS Peco Code 83 HO Crossings
+TURNOUT HO "PECO Code 83 #6 Diamond Crossing SL-8364/SLE-8364"
+ P "Normal" 1 0 2
+ E 0.000000 0.000000 270.000000
+ E 12.035433 0.000000 90.000000
+ E 0.082528 0.993201 279.500000
+ E 11.952905 -0.993201 99.500000
+ S 0 0.000000 0.000000 0.000000 12.035433 0.000000
+ S 0 0.000000 0.082528 0.993201 11.952905 -0.993201
+ END
+TURNOUT HO "PECO Code 83 90d Crossing SL-8390"
+ P "Normal" 1 0 2
+ E 0.000000 0.000000 270.000000
+ E 2.000000 0.000000 90.000000
+ E 1.000000 -1.000000 180.000000
+ E 1.000000 1.000000 0.000000
+ S 0 0.000000 0.000000 0.000000 2.000000 0.000000
+ S 0 0.000000 1.000000 1.000000 1.000000 -1.000000
+ END
+
+SUBCONTENTS Peco Code 83 HO Curved Turnouts
+TURNOUT HO "Peco Code 83 #7 Curved Left Turnout SL-8377/SLE-8377"
+ P "Normal" 1 4 5
+ P "Reverse" 1 2 3
+ E 0.000000 0.000000 270.000000
+ E 11.106693 0.984252 81.000000
+ E 10.865748 1.968504 72.000000
+ S 0 0.000000 0.000000 0.000000 0.649600 0.000000
+ C 0 0.000000 -26.251070 0.649635 26.251070 161.999924 18.000152
+ S 0 0.000000 8.761686 1.284838 10.865748 1.968504
+ C 0 0.000000 -53.910688 0.649672 53.910688 170.999924 9.000152
+ S 0 0.000000 9.083224 0.663751 11.106693 0.984252
+ END
+TURNOUT HO "Peco Code 83 #7 Curved Right Turnout SL-8376/SLE-8376"
+ P "Normal" 1 4 5
+ P "Reverse" 1 2 3
+ E 0.000000 0.000000 270.000000
+ E 11.106693 -0.984252 99.000000
+ E 10.865748 -1.968504 108.000000
+ S 0 0.000000 0.000000 0.000000 0.649600 0.000000
+ C 0 0.000000 26.251070 0.649496 -26.251070 0.000076 18.000152
+ S 0 0.000000 8.761686 -1.284838 10.865748 -1.968504
+ C 0 0.000000 53.910688 0.649385 -53.910688 0.000076 9.000152
+ S 0 0.000000 9.083224 -0.663751 11.106693 -0.984252
+ END
+SUBCONTENTS Peco Code 83 HO Slip Turnouts
+TURNOUT HO "Peco Code 83 #6 Double Slip Switch SL-U8363"
+ P "Normal" 1 2 3 0 4 5 6
+ P "Reverse" 1 7 6 0 4 8 3
+ E 0.000000 0.000000 270.000000
+ E 12.035433 0.000000 90.000000
+ E 0.082528 0.993201 279.500000
+ E 11.952905 -0.993201 99.500000
+ S 0 0.000000 0.000000 0.000000 1.299468 0.000000
+ S 0 0.000000 1.299468 0.000000 10.735965 0.000000
+ S 0 0.000000 10.735965 0.000000 12.035433 0.000000
+ S 0 0.000000 0.082528 0.993201 1.363761 0.778782
+ S 0 0.000000 1.363761 0.778782 10.671672 -0.778782
+ S 0 0.000000 10.671672 -0.778782 11.952905 -0.993201
+ C 0 0.000000 56.784006 1.299241 -56.784006 0.000076 9.500152
+ C 0 0.000000 -56.784006 10.736040 56.783993 180.000076 9.500152
+ END
diff --git a/app/lib/xtrkcad.desktop b/app/lib/xtrkcad.desktop
index 5b09cdc..a5f9dd6 100644
--- a/app/lib/xtrkcad.desktop
+++ b/app/lib/xtrkcad.desktop
@@ -3,7 +3,7 @@ Encoding=UTF-8
Name=XTrackCAD
Comment=Design model railroad layouts
Exec=xtrkcad
-Icon=xtrkcad
+Icon=xtrkcad.png
Terminal=false
Type=Application
-Categories=Application;Railroad;Game
+Categories=Graphics;Game \ No newline at end of file
diff --git a/app/lib/icon.png b/app/lib/xtrkcad.png
index 4cdcdba..4cdcdba 100644
--- a/app/lib/icon.png
+++ b/app/lib/xtrkcad.png
Binary files differ
diff --git a/app/lib/xtrkcad.xtq b/app/lib/xtrkcad.xtq
index be01d88..7b661e6 100644
--- a/app/lib/xtrkcad.xtq
+++ b/app/lib/xtrkcad.xtq
@@ -142,6 +142,10 @@ SCALE TTn3.5, 120.0, 0.3543
1560,37.5,1080
2160,45,1440
2640,52.5,1800
+SCALE TTi, 120.0, 0.177
+ 1560,37.5,1080
+ 2160,45,1440
+ 2640,52.5,1800
SCALE Z, 220.0, 0.256
1560,37.5,1080
2160,45,1440
diff --git a/app/tools/halibut/bk_html.c b/app/tools/halibut/bk_html.c
index 8b5443b..4f7c49b 100644
--- a/app/tools/halibut/bk_html.c
+++ b/app/tools/halibut/bk_html.c
@@ -54,7 +54,8 @@ typedef struct {
char *index_filename;
char *template_filename;
char *single_filename;
- char *chm_filename, *hhp_filename, *hhc_filename, *hhk_filename;
+ char *chm_filename, *hhp_filename, *hhc_filename, *hhk_filename;
+ char *appletoc_filename;
char **template_fragments;
int ntfragments;
char *head_end, *body_start, *body_end, *addr_start, *addr_end;
@@ -100,7 +101,7 @@ struct htmlsect {
htmlsect *next, *parent;
htmlfile *file;
paragraph *title, *text;
- enum { NORMAL, TOP, INDEX } type;
+ enum { NORMAL, TOP, INDEX, APPLEINDEX } type;
int contents_depth;
char **fragments;
};
@@ -235,7 +236,7 @@ static char *html_sanitise_filename(htmlfilelist *files, char *text);
static void html_contents_entry(htmloutput *ho, int depth, htmlsect *s,
htmlfile *thisfile, keywordlist *keywords,
- htmlconfig *cfg);
+ htmlconfig *cfg, int toc_yes);
static void html_section_title(htmloutput *ho, htmlsect *s,
htmlfile *thisfile, keywordlist *keywords,
htmlconfig *cfg, int real);
@@ -268,6 +269,7 @@ static htmlconfig html_configure(paragraph *source) {
ret.template_filename = dupstr("%n.html");
ret.chm_filename = ret.hhp_filename = NULL;
ret.hhc_filename = ret.hhk_filename = NULL;
+ ret.appletoc_filename = NULL;
ret.ntfragments = 1;
ret.template_fragments = snewn(ret.ntfragments, char *);
ret.template_fragments[0] = dupstr("%b");
@@ -517,6 +519,9 @@ static htmlconfig html_configure(paragraph *source) {
} else if (!ustricmp(k, L"html-mshtmlhelp-index")) {
sfree(ret.hhk_filename);
ret.hhk_filename = dupstr(adv(p->origkeyword));
+ } else if (!ustricmp(k, L"html-applehelp-toc")) {
+ sfree(ret.appletoc_filename);
+ ret.appletoc_filename = dupstr(adv(p->origkeyword));
}
}
}
@@ -539,6 +544,7 @@ static htmlconfig html_configure(paragraph *source) {
sfree(ret.hhc_filename); ret.hhc_filename = NULL;
sfree(ret.hhk_filename); ret.hhk_filename = NULL;
}
+
/*
* Now process fallbacks on quote characters.
@@ -839,7 +845,7 @@ void html_backend(paragraph *sourceform, keywordlist *keywords,
* output the section text
* - for each section which is not in the file but which has a
* parent that is, we output a contents entry for the
- * section if appropriate
+ * section if appropriate/
* - finally, we output the file trailer and close the file.
*/
{
@@ -1007,12 +1013,14 @@ void html_backend(paragraph *sourceform, keywordlist *keywords,
for (s = sects.head; s; s = s->next) {
if (s->file == f && s->text) {
for (p = s->text;
- p && (p == s->text || p->type == para_Title ||
- !is_heading_type(p->type));
+ p && (p == s->text || p->type == para_Title
+ || !is_heading_type(p->type)
+ );
p = p->next) {
if (p->type == para_Config) {
if (!ustricmp(p->keyword, L"html-local-head")) {
html_raw(&ho, adv(p->origkeyword));
+ html_nl(&ho);
}
}
}
@@ -1023,13 +1031,15 @@ void html_backend(paragraph *sourceform, keywordlist *keywords,
html_nl(&ho);
if (conf.body_tag)
- html_raw(&ho, conf.body_tag);
+ html_raw(&ho, conf.body_tag);
else
- element_open(&ho, "body");
+ element_open(&ho, "body");
html_nl(&ho);
- if (conf.body_start)
- html_raw(&ho, conf.body_start);
+ if (conf.body_start) {
+ html_raw(&ho, conf.body_start);
+ html_nl(&ho);
+ }
/*
* Write out a nav bar. Special case: we don't do this
@@ -1084,6 +1094,7 @@ void html_backend(paragraph *sourceform, keywordlist *keywords,
}
prevf = f;
+
/*
* Write out a prefix TOC for the file (if a leaf file).
*
@@ -1149,9 +1160,9 @@ void html_backend(paragraph *sourceform, keywordlist *keywords,
assert(hlevel >= 1);
html_contents_entry(&ho, hlevel, s,
- f, keywords, &conf);
+ f, keywords, &conf, 0);
}
- html_contents_entry(&ho, 0, NULL, f, keywords, &conf);
+ html_contents_entry(&ho, 0, NULL, f, keywords, &conf, 0);
}
}
@@ -1204,7 +1215,7 @@ void html_backend(paragraph *sourceform, keywordlist *keywords,
*/
if (adepth <= a->contents_depth) {
html_contents_entry(&ho, adepth, s,
- f, keywords, &conf);
+ f, keywords, &conf, 0);
}
}
}
@@ -1213,7 +1224,7 @@ void html_backend(paragraph *sourceform, keywordlist *keywords,
int hlevel;
char htag[3];
- html_contents_entry(&ho, 0, NULL, f, keywords, &conf);
+ html_contents_entry(&ho, 0, NULL, f, keywords, &conf, 0);
/*
* Display the section heading.
@@ -1440,7 +1451,7 @@ void html_backend(paragraph *sourceform, keywordlist *keywords,
sfree(stackhead);
}
- if (s->type == INDEX) {
+ if (s->type == INDEX ) {
indexentry *entry;
int i;
@@ -1503,7 +1514,7 @@ void html_backend(paragraph *sourceform, keywordlist *keywords,
}
}
- html_contents_entry(&ho, 0, NULL, f, keywords, &conf);
+ html_contents_entry(&ho, 0, NULL, f, keywords, &conf, 0);
html_nl(&ho);
{
@@ -1593,6 +1604,78 @@ void html_backend(paragraph *sourceform, keywordlist *keywords,
}
}
+ /* APPLE TOC only has list entries and all entries are remote */
+ /*
+ * Write out the whole TOC in the TOC file.
+ *
+ */
+
+ if (conf.appletoc_filename) {
+ htmlsect *s, *top;
+ htmlfile *f;
+ htmloutput ho;
+ ho.charset = conf.output_charset;
+ ho.restrict_charset = conf.restrict_charset;
+ ho.cstate = charset_init_state;
+ ho.ver = conf.htmlver;
+ ho.state = HO_NEUTRAL;
+ ho.contents_level = 0;
+ ho.hackflags = 0; /* none of these thankyouverymuch */
+ ho.hacklimit = -1;
+
+ ho.fp = fopen(conf.appletoc_filename, "w");
+ if (!ho.fp)
+ error(err_cantopenw, conf.appletoc_filename);
+
+ /* Find TOP section */
+ s = sects.head;
+
+ html_contents_entry(&ho, 1, s, NULL, keywords, &conf, TRUE);
+
+ /* Loop through all sections */
+ for (s = sects.head; s; s = s->next) {
+ if (s->type == TOP) {
+ /*
+ * This is the head - ignore as we just wrote out its entry.
+ */
+ } else {
+ /*
+ * Doesn't contain the TOP so it is
+ * a descendant we consider it for the
+ * main TOC.
+ */
+ htmlsect *a, *ac;
+ int depth, adepth;
+ /*
+ * Search up from this section until we find
+ * the highest-level one
+ */
+ depth = adepth = 0;
+ a = NULL;
+ for (ac = s; ac; ac = ac->parent) {
+ if (ac->type == TOP) {
+ a = ac;
+ adepth = depth;
+ }
+ depth++;
+ }
+ if (a) {
+
+ html_contents_entry(&ho, adepth, s,
+ NULL, keywords, &conf, TRUE);
+ }
+ }
+ }
+ /*
+ * Close the entries
+ */
+ html_contents_entry(&ho, 0, NULL, NULL, keywords, &conf, TRUE);
+ cleanup(&ho);
+
+ }
+
+ /* End of Apple TOC */
+
/*
* Before we start outputting the HTML Help files, check
* whether there's even going to _be_ an index file: we omit it
@@ -1703,6 +1786,9 @@ void html_backend(paragraph *sourceform, keywordlist *keywords,
fclose(ho.fp);
}
+
+
+
if (conf.hhc_filename) {
htmlfile *f;
htmlsect *s, *a;
@@ -2139,8 +2225,16 @@ static void html_words(htmloutput *ho, word *words, int flags,
sfree(c);
}
break;
+ case word_Anchor:
+ if (flags & LINKS) {
+ element_empty( ho, "a");
+ c = utoa_dup(w->text, CS_ASCII);
+ element_attr(ho, "name", c);
+ sfree(c);
+ }
+ break;
case word_Graphic:
- element_open( ho, "img");
+ element_empty( ho, "img");
c = utoa_dup(w->text, CS_ASCII);
element_attr(ho, "src", c);
return_to_neutral(ho);
@@ -2160,6 +2254,7 @@ static void html_words(htmloutput *ho, word *words, int flags,
assert(s);
html_href(ho, file, s->file, s->fragments[0]);
+
}
break;
case word_HyperEnd:
@@ -2490,7 +2585,6 @@ static void html_href(htmloutput *ho, htmlfile *thisfile,
{
rdstringc rs = { 0, 0, NULL };
char *url;
-
if (targetfile != thisfile)
rdaddsc(&rs, targetfile->filename);
if (targetfrag) {
@@ -2708,37 +2802,52 @@ static char *html_sanitise_filename(htmlfilelist *files, char *text)
static void html_contents_entry(htmloutput *ho, int depth, htmlsect *s,
htmlfile *thisfile, keywordlist *keywords,
- htmlconfig *cfg)
+ htmlconfig *cfg, int toc_yes)
{
- if (ho->contents_level >= depth && ho->contents_level > 0) {
- element_close(ho, "li");
- html_nl(ho);
+
+
+ while (ho->contents_level > depth) {
+ element_close(ho, "ul");
+ ho->contents_level--;
+ html_nl(ho);
+ if (toc_yes && ho->contents_level == 1 && depth == 1) {
+ element_close(ho, "div");
+ html_nl(ho);
+ }
}
+
- while (ho->contents_level > depth) {
- element_close(ho, "ul");
- ho->contents_level--;
- if (ho->contents_level > 0) {
- element_close(ho, "li");
- }
- html_nl(ho);
- }
while (ho->contents_level < depth) {
- html_nl(ho);
- element_open(ho, "ul");
- html_nl(ho);
- ho->contents_level++;
+ if (toc_yes && ho->contents_level == 1 && depth == 2) {
+ element_open(ho,"div");
+ element_attr(ho,"class","panel");
+ html_nl(ho);
+ }
+ element_open(ho, "ul");
+ if (toc_yes && ho->contents_level < 1)
+ element_attr(ho,"class","top-list");
+ html_nl(ho);
+ ho->contents_level++;
}
if (!s)
- return;
+ return;
element_open(ho, "li");
+ if (toc_yes && ho->contents_level > 0 && depth == 1) {
+ element_open(ho,"button");
+ element_attr(ho,"class","accordion");
+ element_close(ho,"button");
+ }
+
html_href(ho, thisfile, s->file, s->fragments[0]);
html_section_title(ho, s, thisfile, keywords, cfg, FALSE);
element_close(ho, "a");
- /* <li> will be closed by a later invocation */
+ element_close(ho, "li");
+ html_nl(ho);
+
+
}
static void html_section_title(htmloutput *ho, htmlsect *s, htmlfile *thisfile,
@@ -2778,9 +2887,9 @@ static void html_section_title(htmloutput *ho, htmlsect *s, htmlfile *thisfile,
assert(s->type != NORMAL);
/*
* If we're printing the full document title for _real_ and
- * there isn't one, we don't want to print `Preamble' at
+ * there isn't one, won't want to print `Preamble' at
* the top of what ought to just be some text. If we need
- * it in any other context such as TOCs, we need to print
+ * it in any other context such ae ds TOCs, we need to print
* `Preamble'.
*/
if (s->type == TOP && !real)
diff --git a/app/tools/halibut/halibut.h b/app/tools/halibut/halibut.h
index 8fe1f08..aa750bd 100644
--- a/app/tools/halibut/halibut.h
+++ b/app/tools/halibut/halibut.h
@@ -169,6 +169,7 @@ enum {
word_HyperLink, /* (invisible) */
word_HyperEnd, /* (also invisible; no text) */
word_Graphic, /* \G */
+ word_Anchor, /* \IA */
/*
* Back ends may define their own word types beyond here, in
* case they need to use them internally.
diff --git a/app/tools/halibut/input.c b/app/tools/halibut/input.c
index b877508..256d9c6 100644
--- a/app/tools/halibut/input.c
+++ b/app/tools/halibut/input.c
@@ -213,6 +213,7 @@ enum {
c_G, /* graphic */
c_H, /* heading */
c_I, /* invisible index mark */
+ c_IA, /* included anchor */
c_IM, /* index merge/rewrite */
c_K, /* capitalised cross-reference */
c_S, /* aux field is 0, 1, 2, ... */
@@ -1299,6 +1300,8 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx,
wd.type = word_HyperLink;
else if (t.cmd == c_G)
wd.type = word_Graphic;
+ else if (t.cmd == c_IA)
+ wd.type = word_Anchor;
else
wd.type = word_Normal;
dtor(t), t = get_token(in);
diff --git a/app/wlib/gtklib/CMakeLists.txt b/app/wlib/gtklib/CMakeLists.txt
index cce9866..a8cae9f 100644
--- a/app/wlib/gtklib/CMakeLists.txt
+++ b/app/wlib/gtklib/CMakeLists.txt
@@ -4,26 +4,51 @@ FILE(GLOB HEADERS *.h)
INCLUDE (FindGTKUnixPrint.cmake)
SET(SOURCES
- gtkbitmap.c
- gtkbutton.c
- gtkcolor.c
- gtkdraw-cairo.c
+ bitmap.c
+ boxes.c
+ button.c
+ color.c
+ control.c
+ droplist.c
filesel.c
- gtkfont.c
- gtkhelp.c
- gtklist.c
- gtkmenu.c
- gtkmisc.c
- gtksimple.c
- gtksingle.c
- gtksplash.c
- gtktext.c
- gtkwindow.c
- gtkxpm.c
+ font.c
+ help.c
+ lines.c
+ list.c
+ liststore.c
+ main.c
+ menu.c
+ message.c
+ notice.c
+ pixbuf.c
+ png.c
print.c
+ single.c
+ splash.c
+ text.c
+ timer.c
+ tooltip.c
+ treeview.c
+ util.c
+ window.c
wpref.c
+# cproto and cppcheck
+
+# end of refactored sources
+ gtkdraw-cairo.c
)
+IF(APPLE)
+ SET(SOURCES
+ ${SOURCES}
+ osxhelp.c)
+
+ELSE(APPLE)
+ SET(SOURCES
+ ${SOURCES}
+ ixhelp.c)
+ENDIF(APPLE)
+
SET_SOURCE_FILES_PROPERTIES(wpref.c PROPERTIES COMPILE_FLAGS -DEXPORT=)
INCLUDE_DIRECTORIES(${XTrkCAD_BINARY_DIR})
@@ -35,3 +60,4 @@ ADD_LIBRARY(xtrkcad-wlib ${HEADERS} ${SOURCES})
TARGET_LINK_LIBRARIES(xtrkcad-wlib ${GTK_LIBRARIES})
TARGET_LINK_LIBRARIES(xtrkcad-wlib ${GTK_UNIX_PRINT_LIBRARIES})
TARGET_LINK_LIBRARIES(xtrkcad-wlib ${GTK_WEBKIT_LIBRARIES})
+
diff --git a/app/wlib/gtklib/bitmap.c b/app/wlib/gtklib/bitmap.c
new file mode 100644
index 0000000..dc7236b
--- /dev/null
+++ b/app/wlib/gtklib/bitmap.c
@@ -0,0 +1,136 @@
+/** \file bitmap.c
+ * Bitmap creation
+ */
+/* XTrkCad - Model Railroad CAD
+ * Copyright (C) 2009 Daniel Spagnol, 2013 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 <stdlib.h>
+
+#define GTK_DISABLE_SINGLE_INCLUDES
+#define GDK_DISABLE_DEPRECATED
+#define GTK_DISABLE_DEPRECATED
+#define GSEAL_ENABLE
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "gtkint.h"
+
+struct wBitmap_t {
+ WOBJ_COMMON
+};
+
+/**
+ * Create a static control for displaying a bitmap.
+ *
+ * \param parent IN parent window
+ * \param x, y IN position in parent window
+ * \param option IN ignored for now
+ * \param iconP IN icon to use in XPM format
+ * \return the control
+ */
+
+wControl_p
+wBitmapCreate( wWin_p parent, wPos_t x, wPos_t y, long options, wIcon_p iconP )
+{
+ wBitmap_p bt;
+ GdkPixbuf *pixbuf;
+ GtkWidget *image;
+
+ bt = wlibAlloc( parent, B_BITMAP, x, y, NULL, sizeof *bt, NULL );
+ bt->w = iconP->w;
+ bt->h = iconP->h;
+ bt->option = options;
+
+ /*
+ * Depending on the platform, parent->widget->window might still be null
+ * at this point. The window allocation should be forced before creating
+ * the pixmap.
+ */
+ if ( gtk_widget_get_window( parent->widget ) == NULL )
+ gtk_widget_realize( parent->widget ); /* force allocation, if pending */
+
+ /* create the bitmap from supplied xpm data */
+ pixbuf = gdk_pixbuf_new_from_xpm_data( (const char **)iconP->bits );
+ image = gtk_image_new_from_pixbuf( pixbuf );
+ gtk_widget_show( image );
+ g_object_unref( (gpointer)pixbuf );
+
+ bt->widget = gtk_fixed_new();
+ gtk_widget_show( bt->widget );
+ gtk_container_add( GTK_CONTAINER(bt->widget), image );
+
+ wlibComputePos( (wControl_p)bt );
+ wlibControlGetSize( (wControl_p)bt );
+ gtk_fixed_put( GTK_FIXED( parent->widget ), bt->widget, bt->realX, bt->realY );
+
+ return( (wControl_p)bt );
+}
+
+/**
+ * Create a two-tone icon
+ *
+ * \param w IN width of icon
+ * \param h IN height of icon
+ * \param bits IN bitmap
+ * \param color IN color
+ * \returns icon handle
+ */
+
+wIcon_p wIconCreateBitMap( wPos_t w, wPos_t h, const char * bits, wDrawColor color )
+{
+ wIcon_p ip;
+ ip = (wIcon_p)malloc( sizeof *ip );
+ ip->gtkIconType = gtkIcon_bitmap;
+ ip->w = w;
+ ip->h = h;
+ ip->color = color;
+ ip->bits = bits;
+ return ip;
+}
+
+/**
+ * Create an icon from a pixmap
+ * \param pm IN pixmap
+ * \returns icon handle
+ */
+
+wIcon_p wIconCreatePixMap( char *pm[] )
+{
+ wIcon_p ip;
+ ip = (wIcon_p)malloc( sizeof *ip );
+ ip->gtkIconType = gtkIcon_pixmap;
+ ip->w = 0;
+ ip->h = 0;
+ ip->color = 0;
+ ip->bits = pm;
+ return ip;
+}
+
+/**
+ * Set the color a two-tone icon
+ *
+ * \param ip IN icon handle
+ * \param color IN color to use
+ */
+
+void wIconSetColor( wIcon_p ip, wDrawColor color )
+{
+ ip->color = color;
+}
+
diff --git a/app/wlib/gtklib/boxes.c b/app/wlib/gtklib/boxes.c
new file mode 100644
index 0000000..cce6649
--- /dev/null
+++ b/app/wlib/gtklib/boxes.c
@@ -0,0 +1,203 @@
+/** \file boxes.c
+ * Window for drawing a rectangle
+ */
+
+/* XTrkCad - Model Railroad CAD
+ * Copyright (C) 2005 Dave Bullis,
+ * 2016 Martin Fischer <m_fischer@sf.net>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+#define GTK_DISABLE_SINGLE_INCLUDES
+#define GDK_DISABLE_DEPRECATED
+#define GTK_DISABLE_DEPRECATED
+#define GSEAL_ENABLE
+
+#include <cairo.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "gtkint.h"
+
+struct wBox_t {
+ WOBJ_COMMON
+ wBoxType_e boxTyp;
+};
+
+#define B (1)
+#define W (2)
+#define SETCOLOR(ST, S, N ) \
+ if (colors[ST][S][N] == B ) { \
+ cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); \
+ } else { \
+ cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); \
+ }
+
+/**
+ * Set size of box window
+ *
+ * \param b IN window handle
+ * \param w IN new width
+ * \param h IN new height
+ * \return
+ *
+ */
+
+void wBoxSetSize(
+ wBox_p b,
+ wPos_t w,
+ wPos_t h)
+{
+ b->w = w;
+ b->h = h;
+}
+
+/**
+ * Draw the box
+ * \todo too many strokes, remove and test
+ *
+ * \param win IN window handle
+ * \param style IN frame style
+ * \param x IN x position
+ * \param y IN y position
+ * \param w IN width
+ * \param h IN height
+ * \return
+ */
+
+void wlibDrawBox(
+ wWin_p win,
+ wBoxType_e style,
+ wPos_t x,
+ wPos_t y,
+ wPos_t w,
+ wPos_t h)
+{
+ wPos_t x0, y0, x1, y1;
+ GdkDrawable * window;
+ cairo_t *cr;
+ static char colors[8][4][2] = {
+ { /* ThinB */ {B,0}, {B,0}, {B,0}, {B,0} },
+ { /* ThinW */ {W,0}, {W,0}, {W,0}, {W,0} },
+ { /* AboveW */ {W,0}, {W,0}, {B,0}, {B,0} },
+ { /* BelowW */ {B,0}, {B,0}, {W,0}, {W,0} },
+ { /* ThickB */ {B,B}, {B,B}, {B,B}, {B,B} },
+ { /* ThickW */ {W,W}, {W,W}, {W,W}, {W,W} },
+ { /* RidgeW */ {W,B}, {W,B}, {B,W}, {B,W} },
+ { /* TroughW*/ {B,W}, {B,W}, {W,B}, {W,B} }
+ };
+ window = gtk_widget_get_window(win->widget);
+ cr = gdk_cairo_create(window);
+ cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER);
+ cairo_set_line_width(cr, 1.0);
+ x0 = x;
+ x1 = x+w;
+ y0 = y;
+ y1 = y+h;
+ SETCOLOR(style, 0, 0);
+ cairo_move_to(cr, x0, y0);
+ cairo_line_to(cr, x0, y1);
+ cairo_stroke_preserve(cr);
+ SETCOLOR(style, 1, 0);
+ cairo_move_to(cr, x0, y0);
+ cairo_line_to(cr, x1, y0);
+ cairo_stroke_preserve(cr);
+ SETCOLOR(style, 2, 0);
+ cairo_move_to(cr, x1, y1);
+ cairo_line_to(cr, x0+1, y1);
+ cairo_stroke_preserve(cr);
+ SETCOLOR(style, 3, 0);
+ cairo_move_to(cr, x1, y1-1);
+ cairo_line_to(cr, x1, y0+1);
+ cairo_stroke_preserve(cr);
+
+ if (style < wBoxThickB) {
+ return;
+ }
+
+ x0++;
+ y0++;
+ x1--;
+ y1--;
+ SETCOLOR(style, 0, 1);
+ cairo_move_to(cr, x0, y0);
+ cairo_line_to(cr, x0, y1);
+ cairo_stroke_preserve(cr);
+ SETCOLOR(style, 1, 1);
+ cairo_move_to(cr, x0+1, y0);
+ cairo_line_to(cr, x1, y0);
+ cairo_stroke_preserve(cr);
+ SETCOLOR(style, 2, 1);
+ cairo_move_to(cr, x1, y1);
+ cairo_line_to(cr, x0+1, y1);
+ cairo_stroke_preserve(cr);
+ SETCOLOR(style, 3, 1);
+ cairo_move_to(cr, x1, y1-1);
+ cairo_line_to(cr, x1, y0+1);
+ cairo_stroke_preserve(cr);
+ cairo_destroy(cr);
+}
+
+/**
+ * Force repainting of box window
+ *
+ * \param b IN box window
+ * \return
+ */
+
+static void boxRepaint(wControl_p b)
+{
+ wBox_p bb = (wBox_p)(b);
+ wWin_p win = bb->parent;
+ wlibDrawBox(win, bb->boxTyp, bb->realX, bb->realY, bb->w, bb->h);
+}
+
+/**
+ * Create new box
+ *
+ * \param parent IN parent window
+ * \param bx IN x position
+ * \param by IN y position
+ * \param labelStr IN label text (ignored)
+ * \param boxTyp IN style
+ * \param bw IN x width
+ * \param by IN y width
+ * \return window handle for newly created box
+ */
+
+wBox_p wBoxCreate(
+ wWin_p parent,
+ wPos_t bx,
+ wPos_t by,
+ const char * labelStr,
+ wBoxType_e boxTyp,
+ wPos_t bw,
+ wPos_t bh)
+{
+ wBox_p b;
+ b = (wBox_p)wlibAlloc(parent, B_BOX, bx, by, labelStr, sizeof *b, NULL);
+ wlibComputePos((wControl_p)b);
+ b->boxTyp = boxTyp;
+ b->w = bw;
+ b->h = bh;
+ b->repaintProc = boxRepaint;
+ wlibAddButton((wControl_p)b);
+ return b;
+}
diff --git a/app/wlib/gtklib/button.c b/app/wlib/gtklib/button.c
new file mode 100644
index 0000000..d9f4880
--- /dev/null
+++ b/app/wlib/gtklib/button.c
@@ -0,0 +1,630 @@
+/** \file button.c
+ * Toolbar button creation and handling
+ */
+
+/* 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 <stdlib.h>
+
+#define GTK_DISABLE_SINGLE_INCLUDES
+#define GDK_DISABLE_DEPRECATED
+#define GTK_DISABLE_DEPRECATED
+#define GSEAL_ENABLE
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "gtkint.h"
+#include "i18n.h"
+
+#define MIN_BUTTON_WIDTH (80)
+
+/*
+ *****************************************************************************
+ *
+ * Simple Buttons
+ *
+ *****************************************************************************
+ */
+
+/**
+ * Set the state of the button
+ *
+ * \param bb IN the button
+ * \param value IN TRUE for active, FALSE for inactive
+ */
+
+void wButtonSetBusy(wButton_p bb, int value)
+{
+ bb->recursion++;
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bb->widget), value);
+ bb->recursion--;
+ bb->busy = value;
+}
+
+/**
+ * Set the label of a button, does also allow to set an icon
+ *
+ * \param widget IN
+ * \param option IN
+ * \param labelStr IN
+ * \param labelG IN
+ * \param imageG IN
+ */
+
+void wlibSetLabel(
+ GtkWidget *widget,
+ long option,
+ const char * labelStr,
+ GtkLabel * * labelG,
+ GtkWidget * * imageG)
+{
+ wIcon_p bm;
+ GdkBitmap * mask;
+
+ if (widget == 0) {
+ abort();
+ }
+
+ if (labelStr) {
+ if (option&BO_ICON) {
+ GdkPixbuf *pixbuf;
+
+ bm = (wIcon_p)labelStr;
+
+ if (bm->gtkIconType == gtkIcon_pixmap) {
+ pixbuf = gdk_pixbuf_new_from_xpm_data((const char**)bm->bits);
+ } else {
+ pixbuf = wlibPixbufFromXBM( bm );
+ }
+ if (*imageG==NULL) {
+ *imageG = gtk_image_new_from_pixbuf(pixbuf);
+ gtk_container_add(GTK_CONTAINER(widget), *imageG);
+ gtk_widget_show(*imageG);
+ } else {
+ gtk_image_set_from_pixbuf(GTK_IMAGE(*imageG), pixbuf);
+ }
+
+ g_object_unref(pixbuf);
+ } else {
+ if (*labelG==NULL) {
+ *labelG = (GtkLabel*)gtk_label_new(wlibConvertInput(labelStr));
+ gtk_container_add(GTK_CONTAINER(widget), (GtkWidget*)*labelG);
+ gtk_widget_show((GtkWidget*)*labelG);
+ } else {
+ gtk_label_set_text(*labelG, wlibConvertInput(labelStr));
+ }
+ }
+ }
+}
+
+/**
+ * Change only the text label of a button
+ * \param bb IN button handle
+ * \param labelStr IN new label string
+ */
+
+void wButtonSetLabel(wButton_p bb, const char * labelStr)
+{
+ wlibSetLabel(bb->widget, bb->option, labelStr, &bb->labelG, &bb->imageG);
+}
+
+/**
+ * Perform the user callback function
+ *
+ * \param bb IN button handle
+ */
+
+void wlibButtonDoAction(
+ wButton_p bb)
+{
+ if (bb->action) {
+ bb->action(bb->data);
+ }
+}
+
+/**
+ * Signal handler for button push
+ * \param widget IN the widget
+ * \param value IN the button handle (same as widget???)
+ */
+
+static void pushButt(
+ GtkWidget *widget,
+ gpointer value)
+{
+ wButton_p b = (wButton_p)value;
+
+ if (debugWindow >= 2) {
+ printf("%s button pushed\n", b->labelStr?b->labelStr:"No label");
+ }
+
+ if (b->recursion) {
+ return;
+ }
+
+ if (b->action) {
+ b->action(b->data);
+ }
+
+ if (!b->busy) {
+ b->recursion++;
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b->widget), FALSE);
+ b->recursion--;
+ }
+}
+
+/**
+ * Create a button
+ *
+ * \param parent IN parent window
+ * \param x IN X-position
+ * \param y IN Y-position
+ * \param helpStr IN Help string
+ * \param labelStr IN Label
+ * \param option IN Options
+ * \param width IN Width of button
+ * \param action IN Callback
+ * \param data IN User data as context
+ * \returns button widget
+ */
+
+wButton_p wButtonCreate(
+ wWin_p parent,
+ wPos_t x,
+ wPos_t y,
+ const char * helpStr,
+ const char * labelStr,
+ long option,
+ wPos_t width,
+ wButtonCallBack_p action,
+ void * data)
+{
+ wButton_p b;
+ b = wlibAlloc(parent, B_BUTTON, x, y, labelStr, sizeof *b, data);
+ b->option = option;
+ b->action = action;
+ wlibComputePos((wControl_p)b);
+
+ b->widget = gtk_toggle_button_new();
+ g_signal_connect(GTK_OBJECT(b->widget), "clicked",
+ G_CALLBACK(pushButt), b);
+ if (width > 0) {
+ gtk_widget_set_size_request(b->widget, width, -1);
+ }
+ if( labelStr ){
+ wButtonSetLabel(b, labelStr);
+ }
+
+ gtk_fixed_put(GTK_FIXED(parent->widget), b->widget, b->realX, b->realY);
+
+ if (option & BB_DEFAULT) {
+ gtk_widget_set_can_default(b->widget, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(b->widget);
+ gtk_window_set_default(GTK_WINDOW(parent->gtkwin), b->widget);
+ }
+
+ wlibControlGetSize((wControl_p)b);
+
+ if (width == 0 && b->w < MIN_BUTTON_WIDTH && (b->option&BO_ICON)==0) {
+ b->w = MIN_BUTTON_WIDTH;
+ gtk_widget_set_size_request(b->widget, b->w, b->h);
+ }
+
+ gtk_widget_show(b->widget);
+ wlibAddButton((wControl_p)b);
+ wlibAddHelpString(b->widget, helpStr);
+ return b;
+}
+
+
+/*
+ *****************************************************************************
+ *
+ * Choice Boxes
+ *
+ *****************************************************************************
+ */
+
+struct wChoice_t {
+ WOBJ_COMMON
+ long *valueP;
+ wChoiceCallBack_p action;
+ int recursion;
+};
+
+
+/**
+ * Get the state of a group of buttons. If the group consists of
+ * radio buttons, the return value is the index of the selected button
+ * or -1 for none. If toggle buttons are checked, a bit is set for each
+ * button that is active.
+ *
+ * \param bc IN
+ * \returns state of group
+ */
+
+static long choiceGetValue(
+ wChoice_p bc)
+{
+ GList * child, * children;
+ long value, inx;
+
+ if (bc->type == B_TOGGLE) {
+ value = 0;
+ } else {
+ value = -1;
+ }
+
+ for (children=child=gtk_container_get_children(GTK_CONTAINER(bc->widget)),inx=0;
+ child; child=child->next,inx++) {
+ if (gtk_toggle_button_get_active(child->data)) {
+ if (bc->type == B_TOGGLE) {
+ value |= (1<<inx);
+ } else {
+ value = inx;
+ }
+ }
+ }
+
+ if (children) {
+ g_list_free(children);
+ }
+
+ return value;
+}
+
+/**
+ * Set the active radio button in a group
+ *
+ * \param bc IN button group
+ * \param value IN index of active button
+ */
+
+void wRadioSetValue(
+ wChoice_p bc, /* Radio box */
+ long value) /* Value */
+{
+ GList * child, * children;
+ long inx;
+
+ for (children=child=gtk_container_get_children(GTK_CONTAINER(bc->widget)),inx=0;
+ child; child=child->next,inx++) {
+ if (inx == value) {
+ bc->recursion++;
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(child->data), TRUE);
+ bc->recursion--;
+ }
+ }
+
+ if (children) {
+ g_list_free(children);
+ }
+}
+
+/**
+ * Get the active button from a group of radio buttons
+ *
+ * \param bc IN
+ * \returns
+ */
+
+long wRadioGetValue(
+ wChoice_p bc) /* Radio box */
+{
+ return choiceGetValue(bc);
+}
+
+/**
+ * Set a group of toggle buttons from a bitfield
+ *
+ * \param bc IN button group
+ * \param value IN bitfield
+ */
+
+void wToggleSetValue(
+ wChoice_p bc, /* Toggle box */
+ long value) /* Values */
+{
+ GList * child, * children;
+ long inx;
+ bc->recursion++;
+
+ for (children=child=gtk_container_get_children(GTK_CONTAINER(bc->widget)),inx=0;
+ child; child=child->next,inx++) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(child->data),
+ (value&(1<<inx))!=0);
+ }
+
+ if (children) {
+ g_list_free(children);
+ }
+
+ bc->recursion--;
+}
+
+
+/**
+ * Get the active buttons from a group of toggle buttons
+ *
+ * \param b IN
+ * \returns
+ */
+
+long wToggleGetValue(
+ wChoice_p b) /* Toggle box */
+{
+ return choiceGetValue(b);
+}
+
+/**
+ * Signal handler for button selection in radio buttons and toggle
+ * button group
+ *
+ * \param widget IN the button group
+ * \param b IN user data (button group????)
+ * \returns always 1
+ */
+
+static int pushChoice(
+ GtkWidget *widget,
+ gpointer b)
+{
+ wChoice_p bc = (wChoice_p)b;
+ long value = choiceGetValue(bc);
+
+ if (debugWindow >= 2) {
+ printf("%s choice pushed = %ld\n", bc->labelStr?bc->labelStr:"No label",
+ value);
+ }
+
+ if (bc->type == B_RADIO &&
+ !(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))) {
+ return 1;
+ }
+
+ if (bc->recursion) {
+ return 1;
+ }
+
+ if (bc->valueP) {
+ *bc->valueP = value;
+ }
+
+ if (bc->action) {
+ bc->action(value, bc->data);
+ }
+
+ return 1;
+}
+
+/**
+ * Signal handler used to draw a frame around a widget, used to visually
+ * group several buttons together
+ *
+ * \param b IN widget
+ */
+
+static void choiceRepaint(
+ wControl_p b)
+{
+ wChoice_p bc = (wChoice_p)b;
+
+ if (gtk_widget_get_visible(b->widget)) {
+ wlibDrawBox(bc->parent, wBoxBelow, bc->realX-1, bc->realY-1, bc->w+1, bc->h+1);
+ }
+}
+
+/**
+ * Create a group of radio buttons.
+ *
+ * \param parent IN parent window
+ * \param x IN X-position
+ * \param y IN Y-position
+ * \param helpStr IN Help string
+ * \param labelStr IN Label
+ * \param option IN Options
+ * \param labels IN Labels
+ * \param valueP IN Selected value
+ * \param action IN Callback
+ * \param data IN User data as context
+ * \returns radio button widget
+ */
+
+wChoice_p wRadioCreate(
+ wWin_p parent,
+ wPos_t x,
+ wPos_t y,
+ const char * helpStr,
+ const char * labelStr,
+ long option,
+ const char **labels,
+ long *valueP,
+ wChoiceCallBack_p action,
+ void *data)
+{
+ wChoice_p b;
+ const char ** label;
+ GtkWidget *butt0=NULL, *butt;
+
+ if ((option & BC_NOBORDER)==0) {
+ if (x>=0) {
+ x++;
+ } else {
+ x--;
+ }
+
+ if (y>=0) {
+ y++;
+ } else {
+ y--;
+ }
+ }
+
+ b = wlibAlloc(parent, B_RADIO, x, y, labelStr, sizeof *b, data);
+ b->option = option;
+ b->action = action;
+ b->valueP = valueP;
+ wlibComputePos((wControl_p)b);
+
+ if (option&BC_HORZ) {
+ b->widget = gtk_hbox_new(FALSE, 0);
+ } else {
+ b->widget = gtk_vbox_new(FALSE, 0);
+ }
+
+ if (b->widget == 0) {
+ abort();
+ }
+
+ for (label=labels; *label; label++) {
+ butt = gtk_radio_button_new_with_label(
+ butt0?gtk_radio_button_get_group(GTK_RADIO_BUTTON(butt0)):NULL, _(*label));
+
+ if (butt0==NULL) {
+ butt0 = butt;
+ }
+
+ gtk_box_pack_start(GTK_BOX(b->widget), butt, TRUE, TRUE, 0);
+ gtk_widget_show(butt);
+ g_signal_connect(GTK_OBJECT(butt), "toggled",
+ G_CALLBACK(pushChoice), b);
+ wlibAddHelpString(butt, helpStr);
+ }
+
+ if (option & BB_DEFAULT) {
+ gtk_widget_set_can_default(b->widget, TRUE);
+ gtk_widget_grab_default(b->widget);
+ }
+
+ if (valueP) {
+ wRadioSetValue(b, *valueP);
+ }
+
+ if ((option & BC_NOBORDER)==0) {
+ b->repaintProc = choiceRepaint;
+ b->w += 2;
+ b->h += 2;
+ }
+
+ gtk_fixed_put(GTK_FIXED(parent->widget), b->widget, b->realX, b->realY);
+ wlibControlGetSize((wControl_p)b);
+
+ if (labelStr) {
+ b->labelW = wlibAddLabel((wControl_p)b, labelStr);
+ }
+
+ gtk_widget_show(b->widget);
+ wlibAddButton((wControl_p)b);
+ return b;
+}
+
+/**
+ * Create a group of toggle buttons.
+ *
+ * \param parent IN parent window
+ * \param x IN X-position
+ * \param y IN Y-position
+ * \param helpStr IN Help string
+ * \param labelStr IN Label
+ * \param option IN Options
+ * \param labels IN Labels
+ * \param valueP IN Selected value
+ * \param action IN Callback
+ * \param data IN User data as context
+ * \returns toggle button widget
+ */
+
+wChoice_p wToggleCreate(
+ wWin_p parent,
+ wPos_t x,
+ wPos_t y,
+ const char * helpStr,
+ const char * labelStr,
+ long option,
+ const char **labels,
+ long *valueP,
+ wChoiceCallBack_p action,
+ void *data)
+{
+ wChoice_p b;
+ const char ** label;
+
+ if ((option & BC_NOBORDER)==0) {
+ if (x>=0) {
+ x++;
+ } else {
+ x--;
+ }
+
+ if (y>=0) {
+ y++;
+ } else {
+ y--;
+ }
+ }
+
+ b = wlibAlloc(parent, B_TOGGLE, x, y, labelStr, sizeof *b, data);
+ b->option = option;
+ b->action = action;
+ wlibComputePos((wControl_p)b);
+
+ if (option&BC_HORZ) {
+ b->widget = gtk_hbox_new(FALSE, 0);
+ } else {
+ b->widget = gtk_vbox_new(FALSE, 0);
+ }
+
+ if (b->widget == 0) {
+ abort();
+ }
+
+ for (label=labels; *label; label++) {
+ GtkWidget *butt;
+
+ butt = gtk_check_button_new_with_label(_(*label));
+ gtk_box_pack_start(GTK_BOX(b->widget), butt, TRUE, TRUE, 0);
+ gtk_widget_show(butt);
+ g_signal_connect(GTK_OBJECT(butt), "toggled",
+ G_CALLBACK(pushChoice), b);
+ wlibAddHelpString(butt, helpStr);
+ }
+
+ if (valueP) {
+ wToggleSetValue(b, *valueP);
+ }
+
+ if ((option & BC_NOBORDER)==0) {
+ b->repaintProc = choiceRepaint;
+ b->w += 2;
+ b->h += 2;
+ }
+
+ gtk_fixed_put(GTK_FIXED(parent->widget), b->widget, b->realX, b->realY);
+ wlibControlGetSize((wControl_p)b);
+
+ if (labelStr) {
+ b->labelW = wlibAddLabel((wControl_p)b, labelStr);
+ }
+
+ gtk_widget_show(b->widget);
+ wlibAddButton((wControl_p)b);
+ return b;
+}
diff --git a/app/wlib/gtklib/color.c b/app/wlib/gtklib/color.c
new file mode 100644
index 0000000..64b96ef
--- /dev/null
+++ b/app/wlib/gtklib/color.c
@@ -0,0 +1,466 @@
+/** \file color.c
+ * code for the color selection dialog and color button
+ */
+
+/* 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 <assert.h>
+#include <stdlib.h>
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#define GTK_DISABLE_SINGLE_INCLUDES
+#define GDK_DISABLE_DEPRECATED
+#define GTK_DISABLE_DEPRECATED
+#define GSEAL_ENABLE
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "gtkint.h"
+
+wDrawColor wDrawColorWhite;
+wDrawColor wDrawColorBlack;
+
+#define RGB(R,G,B) ( ((long)((R)&0xFF)<<16) | ((long)((G)&0xFF)<<8) | ((long)((B)&0xFF)) )
+
+#define MAX_COLOR_DISTANCE (3)
+
+static GArray *colorMap_garray = NULL; // Change to use glib array
+
+static colorMap_t colorMap[] = {
+ { 255, 255, 255 }, /* White */
+ { 0, 0, 0 }, /* Black */
+ { 255, 0, 0 }, /* Red */
+ { 0, 255, 0 }, /* Green */
+ { 0, 0, 255 }, /* Blue */
+ { 255, 255, 0 }, /* Yellow */
+ { 255, 0, 255 }, /* Purple */
+ { 0, 255, 255 }, /* Aqua */
+ { 128, 0, 0 }, /* Dk. Red */
+ { 0, 128, 0 }, /* Dk. Green */
+ { 0, 0, 128 }, /* Dk. Blue */
+ { 128, 128, 0 }, /* Dk. Yellow */
+ { 128, 0, 128 }, /* Dk. Purple */
+ { 0, 128, 128 }, /* Dk. Aqua */
+ { 65, 105, 225 }, /* Royal Blue */
+ { 0, 191, 255 }, /* DeepSkyBlue */
+ { 125, 206, 250 }, /* LightSkyBlue */
+ { 70, 130, 180 }, /* Steel Blue */
+ { 176, 224, 230 }, /* Powder Blue */
+ { 127, 255, 212 }, /* Aquamarine */
+ { 46, 139, 87 }, /* SeaGreen */
+ { 152, 251, 152 }, /* PaleGreen */
+ { 124, 252, 0 }, /* LawnGreen */
+ { 50, 205, 50 }, /* LimeGreen */
+ { 34, 139, 34 }, /* ForestGreen */
+ { 255, 215, 0 }, /* Gold */
+ { 188, 143, 143 }, /* RosyBrown */
+ { 139, 69, 19 }, /* SaddleBrown */
+ { 245, 245, 220 }, /* Beige */
+ { 210, 180, 140 }, /* Tan */
+ { 210, 105, 30 }, /* Chocolate */
+ { 165, 42, 42 }, /* Brown */
+ { 255, 165, 0 }, /* Orange */
+ { 255, 127, 80 }, /* Coral */
+ { 255, 99, 71 }, /* Tomato */
+ { 255, 105, 180 }, /* HotPink */
+ { 255, 192, 203 }, /* Pink */
+ { 176, 48, 96 }, /* Maroon */
+ { 238, 130, 238 }, /* Violet */
+ { 160, 32, 240 }, /* Purple */
+ { 16, 16, 16 }, /* Gray */
+ { 32, 32, 32 }, /* Gray */
+ { 48, 48, 48 }, /* Gray */
+ { 64, 64, 64 }, /* Gray */
+ { 80, 80, 80 }, /* Gray */
+ { 96, 96, 96 }, /* Gray */
+ { 112, 112, 122 }, /* Gray */
+ { 128, 128, 128 }, /* Gray */
+ { 144, 144, 144 }, /* Gray */
+ { 160, 160, 160 }, /* Gray */
+ { 176, 176, 176 }, /* Gray */
+ { 192, 192, 192 }, /* Gray */
+ { 208, 208, 208 }, /* Gray */
+ { 224, 224, 224 }, /* Gray */
+ { 240, 240, 240 }, /* Gray */
+ { 0, 0, 0 } /* BlackPixel */
+};
+
+#define NUM_GRAYS (16)
+
+static GdkColormap * gtkColorMap;
+
+static char lastColorChar = '!';
+
+/**
+ * Get a gray color
+ *
+ * \param percent IN gray value required
+ * \return definition for gray color
+ */
+
+wDrawColor wDrawColorGray(
+ int percent)
+{
+ int n;
+ long rgb;
+ n = (percent * (NUM_GRAYS+1)) / 100;
+
+ if (n <= 0) {
+ return wDrawColorBlack;
+ } else if (n > NUM_GRAYS) {
+ return wDrawColorWhite;
+ } else {
+ n = (n*256)/NUM_GRAYS;
+ rgb = RGB(n, n, n);
+ return wDrawFindColor(rgb);
+ }
+}
+
+/**
+ * Get the color map for the main window
+ *
+ * \return
+ */
+
+void wlibGetColorMap(void)
+{
+ if (gtkColorMap) {
+ return;
+ }
+
+ gtkColorMap = gtk_widget_get_colormap(gtkMainW->widget);
+ return;
+}
+
+/**
+ * Initialize a colorMap entry
+ * \todo no idea what this is required for
+ *
+ * \param t IN color code
+ * \return
+ */
+
+static void init_colorMapValue(colorMap_t * t)
+{
+ t->rgb = RGB(t->red, t->green, t->blue);
+ t->normalColor.red = t->red*65535/255;
+ t->normalColor.green = t->green*65535/255;
+ t->normalColor.blue = t->blue*65535/255;
+ gdk_colormap_alloc_color(gtkColorMap, &t->normalColor, FALSE, TRUE);
+ t->invertColor = t->normalColor;
+ t->invertColor.pixel ^= g_array_index(colorMap_garray, colorMap_t,
+ wDrawColorWhite).normalColor.pixel;
+ t->colorChar = lastColorChar++;
+
+ if (lastColorChar >= 0x7F) {
+ lastColorChar = '!'+1;
+ } else if (lastColorChar == '"') {
+ lastColorChar++;
+ }
+}
+
+/**
+ * Allocate a color map and initialize with application default colors
+ *
+ * \return
+ */
+
+static void init_colorMap(void)
+{
+ int gint;
+ colorMap_garray = g_array_sized_new(TRUE, TRUE, sizeof(colorMap_t),
+ sizeof(colorMap)/sizeof(colorMap_t));
+ g_array_append_vals(colorMap_garray, &colorMap,
+ sizeof(colorMap)/sizeof(colorMap_t));
+
+ for (gint=0; gint<colorMap_garray->len; gint++) {
+ init_colorMapValue(&g_array_index(colorMap_garray, colorMap_t, gint));
+ }
+}
+
+/**
+ * Find the closest color from the palette and add a new color if there
+ * is no close match
+ * \todo improve method for finding best match (squared distances)
+ *
+ * \param rgb0 IN desired color
+ * \return palette index of matching color
+ */
+
+wDrawColor wDrawFindColor(
+ long rgb0)
+{
+ wDrawColor cc;
+ int r0, g0, b0;
+ int d0;
+ int i;
+ colorMap_t tempMapValue;
+ wlibGetColorMap();
+ cc = wDrawColorBlack;
+ r0 = (int)(rgb0>>16)&0xFF;
+ g0 = (int)(rgb0>>8)&0xFF;
+ b0 = (int)(rgb0)&0xFF;
+ d0 = 256*3;
+
+ // Initialize garray if needed
+ if (colorMap_garray == NULL) {
+ init_colorMap();
+ }
+
+ // Iterate over entire garray
+ for (i=0; i<colorMap_garray->len; i++) {
+ int d1;
+ colorMap_t * cm_p;
+
+ cm_p = &g_array_index(colorMap_garray, colorMap_t, i);
+ d1 = abs(r0-cm_p->red) + abs(g0-cm_p->green) + abs(b0-cm_p->blue);
+
+ if (d1 == 0) {
+ return i;
+ }
+
+ if (d1 < d0) {
+ d0 = d1;
+ cc = i;
+ }
+ }
+
+ if (d0 <= MAX_COLOR_DISTANCE) {
+ return cc;
+ }
+
+ // No good value - so add one
+ tempMapValue.red = r0;
+ tempMapValue.green = g0;
+ tempMapValue.blue = b0;
+ init_colorMapValue(&tempMapValue);
+ g_array_append_val(colorMap_garray,tempMapValue);
+ return i;
+}
+
+/**
+ * Get the RGB code for a palette entry
+ *
+ * \param color IN the palette index
+ * \return RGB code
+ */
+
+long wDrawGetRGB(
+ wDrawColor color)
+{
+ colorMap_t * colorMap_e;
+ wlibGetColorMap();
+
+ if (colorMap_garray == NULL) {
+ init_colorMap();
+ }
+
+ if (color < 0 || color > colorMap_garray->len) {
+ abort();
+ }
+
+ colorMap_e = &g_array_index(colorMap_garray, colorMap_t, color);
+ return colorMap_e->rgb;
+}
+
+/**
+ * Get the color definition from the palette index
+ *
+ * \param color IN index into palette
+ * \param normal IN normal or inverted color
+ * \return the selected color definition
+ */
+
+GdkColor* wlibGetColor(
+ wDrawColor color,
+ wBool_t normal)
+{
+ colorMap_t * colorMap_e;
+ wlibGetColorMap();
+
+ if (colorMap_garray == NULL) {
+ init_colorMap();
+ }
+
+ if (color < 0 || color > colorMap_garray->len) {
+ abort();
+ }
+
+ colorMap_e = &g_array_index(colorMap_garray, colorMap_t, color);
+
+ if (normal) {
+ return &colorMap_e->normalColor;
+ } else {
+ return &colorMap_e->invertColor;
+ }
+}
+
+
+/*
+ *****************************************************************************
+ *
+ * Color Selection Button
+ *
+ *****************************************************************************
+ */
+
+typedef struct {
+ wDrawColor * valueP;
+ const char * labelStr;
+ wColorSelectButtonCallBack_p action;
+ void * data;
+ wDrawColor color;
+ wButton_p button;
+} colorData_t;
+
+/**
+ * Handle the color-set signal.
+ *
+ * \param widget color button
+ * \param user_data
+ */
+
+static void
+colorChange(GtkColorButton *widget, gpointer user_data)
+{
+ colorData_t *cd = user_data;
+ GdkColor newcolor;
+ long rgb;
+
+ gtk_color_button_get_color(widget, &newcolor);
+
+ rgb = RGB((int)(newcolor.red/256), (int)(newcolor.green/256),
+ (int)(newcolor.blue/256));
+ cd->color = wDrawFindColor(rgb);
+
+ if (cd->valueP) {
+ *(cd->valueP) = cd->color;
+ }
+
+ if (cd->action) {
+ cd->action(cd->data, cd->color);
+ }
+}
+
+/**
+ * Set the color for a color button
+ *
+ * \param bb IN button
+ * \param color IN palette index for color to use
+ * \return describe the return value
+ */
+
+void wColorSelectButtonSetColor(
+ wButton_p bb,
+ wDrawColor color)
+{
+ GdkColor *colorOfButton = wlibGetColor(color, TRUE);
+
+ gtk_color_button_set_color(GTK_COLOR_BUTTON(bb->widget),
+ colorOfButton);
+ ((colorData_t*)((wControl_p)bb)->data)->color = color;
+}
+
+
+/**
+ * Get the current palette index for a color button
+ *
+ * \param bb IN button handle
+ * \return palette index
+ */
+
+wDrawColor wColorSelectButtonGetColor(
+ wButton_p bb)
+{
+ return ((colorData_t*)((wControl_p)bb)->data)->color;
+}
+
+/**
+ * Create the button showing the current paint color and starting the color selection dialog.
+ *
+ * \param IN parent parent window
+ * \param IN x x coordinate
+ * \param IN Y y coordinate
+ * \param IN helpStr balloon help string
+ * \param IN labelStr Button label ???
+ * \param IN option
+ * \param IN width
+ * \param IN valueP Current color ???
+ * \param IN action Button callback procedure
+ * \param IN data ???
+ * \return bb handle for created button
+ */
+
+wButton_p wColorSelectButtonCreate(
+ wWin_p parent,
+ wPos_t x,
+ wPos_t y,
+ const char * helpStr,
+ const char * labelStr,
+ long option,
+ wPos_t width,
+ wDrawColor *valueP,
+ wColorSelectButtonCallBack_p action,
+ void * data)
+{
+ wButton_p b;
+ colorData_t * cd;
+ cd = malloc(sizeof(colorData_t));
+ cd->valueP = valueP;
+ cd->action = action;
+ cd->data = data;
+ cd->labelStr = labelStr;
+ cd->color = (valueP?*valueP:0);
+
+ b = wlibAlloc(parent, B_BUTTON, x, y, labelStr, sizeof *b, cd);
+ b->option = option;
+ wlibComputePos((wControl_p)b);
+
+ b->widget = gtk_color_button_new();
+ GtkStyle *style;
+ style = gtk_widget_get_style(b->widget);
+ style->xthickness = 1;
+ style->ythickness = 1;
+ gtk_widget_set_style(b->widget, style);
+ gtk_widget_set_size_request(GTK_WIDGET(b->widget), 22, 22);
+ g_signal_connect(GTK_OBJECT(b->widget), "color-set",
+ G_CALLBACK(colorChange), cd);
+
+ gtk_fixed_put(GTK_FIXED(parent->widget), b->widget, b->realX, b->realY);
+
+ if (option & BB_DEFAULT) {
+ gtk_widget_set_can_default(b->widget, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(b->widget);
+ gtk_window_set_default(GTK_WINDOW(parent->gtkwin), b->widget);
+ }
+
+ wlibControlGetSize((wControl_p)b);
+
+ gtk_widget_show(b->widget);
+ wlibAddButton((wControl_p)b);
+ wlibAddHelpString(b->widget, helpStr);
+ wColorSelectButtonSetColor(b, (valueP?*valueP:0));
+
+ if (labelStr) {
+ ((wControl_p)b)->labelW = wlibAddLabel((wControl_p)b, labelStr);
+ }
+ return b;
+}
diff --git a/app/wlib/gtklib/control.c b/app/wlib/gtklib/control.c
new file mode 100644
index 0000000..e824c94
--- /dev/null
+++ b/app/wlib/gtklib/control.c
@@ -0,0 +1,283 @@
+/** \file control.c
+ * Control Utilities
+ */
+/*
+ * Copyright 2016 Martin Fischer <m_fischer@sf.net>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define GTK_DISABLE_SINGLE_INCLUDES
+#define GDK_DISABLE_DEPRECATED
+#define GTK_DISABLE_DEPRECATED
+#define GSEAL_ENABLE
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "gtkint.h"
+
+#define GTKCONTROLHILITEWIDTH (3)
+
+/**
+ * Cause the control <b> to be displayed or hidden.
+ * Used to hide control (such as a list) while it is being updated.
+ *
+ * \param b IN Control
+ * \param show IN TRUE for visible
+ */
+
+void wControlShow(
+ wControl_p b,
+ wBool_t show)
+{
+ if (b->type == B_LINES) {
+ wlibLineShow((wLine_p)b, show);
+ return;
+ }
+
+ if (b->widget == NULL) {
+ abort();
+ }
+
+ if (show) {
+ gtk_widget_show(b->widget);
+
+ if (b->label) {
+ gtk_widget_show(b->label);
+ }
+ } else {
+ gtk_widget_hide(b->widget);
+
+ if (b->label) {
+ gtk_widget_hide(b->label);
+ }
+ }
+}
+
+/**
+ * Cause the control <b> to be marked active or inactive.
+ * Inactive controls donot respond to actions.
+ *
+ * \param b IN Control
+ * \param active IN TRUE for active
+ */
+
+void wControlActive(
+ wControl_p b,
+ int active)
+{
+ if (b->widget == NULL) {
+ abort();
+ }
+
+ gtk_widget_set_sensitive(GTK_WIDGET(b->widget), active);
+}
+
+/**
+ * Returns the width of <label>.
+ * This is used for computing window layout.
+ * Typically the width to the longest label is computed and used as
+ * the X-position for <controls>.
+ *
+ * \param label IN label
+ * \returns width of label including some space
+*/
+
+wPos_t wLabelWidth(
+ const char * label)
+{
+ GtkWidget * widget;
+ GtkRequisition requisition;
+ widget = gtk_label_new(wlibConvertInput(label));
+ gtk_widget_size_request(widget, &requisition);
+ gtk_widget_destroy(widget);
+ return requisition.width+8;
+}
+
+/**
+ * Get width of a control
+ *
+ * \param b IN Control
+ * \returns width
+ */
+
+wPos_t wControlGetWidth(
+ wControl_p b)
+{
+ return b->w;
+}
+
+/**
+ * Get height of a control
+ *
+ * \param b IN Control
+ * \returns height
+ */
+
+wPos_t wControlGetHeight(
+ wControl_p b)
+{
+ return b->h;
+}
+
+/**
+ * Get x position of a control
+ *
+ * \param b IN Control
+ * \returns position
+ */
+
+wPos_t wControlGetPosX(
+ wControl_p b) /* Control */
+{
+ return b->realX;
+}
+
+/**
+ * Get y position of a control
+ *
+ * \param b IN Control
+ * \returns position
+ */
+
+wPos_t wControlGetPosY(
+ wControl_p b) /* Control */
+{
+ return b->realY - BORDERSIZE - ((b->parent->option&F_MENUBAR)?MENUH:0);
+}
+
+/**
+ * Set the fixed position of a control within its parent window
+ *
+ * \param b IN control
+ * \param x IN x position
+ * \param y IN y position
+ */
+
+void wControlSetPos(
+ wControl_p b,
+ wPos_t x,
+ wPos_t y)
+{
+ b->realX = x;
+ b->realY = y + BORDERSIZE + ((b->parent->option&F_MENUBAR)?MENUH:0);
+
+ if (b->widget) {
+ gtk_fixed_move(GTK_FIXED(b->parent->widget), b->widget, b->realX, b->realY);
+ }
+
+ if (b->label) {
+ gtk_fixed_move(GTK_FIXED(b->parent->widget), b->label, b->realX-b->labelW,
+ b->realY+LABEL_OFFSET);
+ }
+}
+
+/**
+ * Set the label for a control
+ *
+ * \param b IN control
+ * \param labelStr IN the new label
+ */
+
+void wControlSetLabel(
+ wControl_p b,
+ const char * labelStr)
+{
+ GtkRequisition requisition;
+
+ if (b->label) {
+ gtk_label_set_text(GTK_LABEL(b->label), wlibConvertInput(labelStr));
+ gtk_widget_size_request(b->label, &requisition);
+ b->labelW = requisition.width+8;
+ gtk_fixed_move(GTK_FIXED(b->parent->widget), b->label, b->realX-b->labelW,
+ b->realY+LABEL_OFFSET);
+ } else {
+ b->labelW = wlibAddLabel(b, labelStr);
+ }
+}
+
+/**
+ * Set the context ie. additional user data for a control
+ *
+ * \param b IN control
+ * \param context IN user date
+ */
+
+void wControlSetContext(
+ wControl_p b,
+ void * context)
+{
+ b->data = context;
+}
+
+/**
+ * Not implemented
+ *
+ * \param b IN
+ */
+
+void wControlSetFocus(
+ wControl_p b)
+{
+}
+
+/**
+ * Draw a rectangle around a control
+ * \param b IN the control
+ * \param hilite IN unused
+ * \returns
+ *
+ *
+ */
+void wControlHilite(
+ wControl_p b,
+ wBool_t hilite)
+{
+ cairo_t *cr;
+ int off = GTKCONTROLHILITEWIDTH/2+1;
+
+ if (b->widget == NULL) {
+ return;
+ }
+
+ if (! gtk_widget_get_visible(b->widget)) {
+ return;
+ }
+
+ if (! gtk_widget_get_visible(b->parent->widget)) {
+ return;
+ }
+
+ cr = gdk_cairo_create(gtk_widget_get_window(b->parent->gtkwin));
+ cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
+ cairo_set_operator(cr, CAIRO_OPERATOR_XOR);
+ cairo_set_line_width(cr, GTKCONTROLHILITEWIDTH);
+ cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER);
+ cairo_rectangle(cr,
+ b->realX - GTKCONTROLHILITEWIDTH,
+ b->realY - off,
+ b->w + GTKCONTROLHILITEWIDTH,
+ b->h + off + 1);
+ cairo_stroke(cr);
+ cairo_destroy(cr);
+}
diff --git a/app/wlib/gtklib/droplist.c b/app/wlib/gtklib/droplist.c
new file mode 100644
index 0000000..3252905
--- /dev/null
+++ b/app/wlib/gtklib/droplist.c
@@ -0,0 +1,456 @@
+/** \file droplist.c
+ * Dropdown list functions
+ */
+
+/* XTrkCad - Model Railroad CAD
+ * Copyright (C) Dave Bullis 2005, Martin Fischer 2016
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#define GTK_DISABLE_SINGLE_INCLUDES
+#define GDK_DISABLE_DEPRECATED
+#define GTK_DISABLE_DEPRECATED
+#define GSEAL_ENABLE
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include "gtkint.h"
+#include "i18n.h"
+
+/* define the column count for the tree model */
+#define DROPLIST_TEXTCOLUMNS 1
+
+/**
+ * Add the data columns to the droplist. If dropList has an entry field
+ * the first text column is not added here as this is done by GTK
+ * automatically.
+ *
+ * \param dropList IN
+ * \param columns IN
+ * \returns number of columns created
+ */
+
+int
+wlibDropListAddColumns(GtkWidget *dropList, int columns)
+{
+ int i;
+ int start = 0;
+ GtkCellRenderer *cell;
+
+ if (gtk_combo_box_get_has_entry(GTK_COMBO_BOX(dropList))) {
+ start = 1;
+ }
+
+ /* Create cell renderer. */
+ cell = gtk_cell_renderer_text_new();
+
+ for (i = start; i < columns; i++) {
+ /* Pack it into the droplist */
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dropList), cell, TRUE);
+
+ /* Connect renderer to data source */
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(dropList),
+ cell,
+ "text",
+ LISTCOL_TEXT + i,
+ NULL);
+ }
+
+ return (i);
+}
+
+/**
+ * Get the number of rows in drop list
+ *
+ * \param b IN widget
+ * \return number of rows
+ */
+
+wIndex_t wDropListGetCount(wList_p b)
+{
+ return (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(b->listStore), NULL));
+}
+
+/**
+ * Clear the whole droplist
+ *
+ * \param b IN the droplist
+ * \return
+ */
+
+void
+wDropListClear(wList_p b)
+{
+ wlibListStoreClear(b->listStore);
+}
+
+/**
+ * Get the user data / context information for a row in the droplist
+ * \param b IN widget
+ * \param inx IN row
+ * \returns pointer to context information
+ */
+
+void *wDropListGetItemContext(wList_p b, wIndex_t inx)
+{
+ GtkTreeIter iter;
+ wListItem_p data = NULL;
+
+ if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(b->listStore), &iter, NULL,
+ inx)) {
+ gtk_tree_model_get(GTK_TREE_MODEL(b->listStore),
+ &iter,
+ LISTCOL_DATA, (void *)&data,
+ -1);
+ }
+
+ if (data) {
+ return (data->itemData);
+ } else {
+ return (NULL);
+ }
+}
+
+/**
+ * Add an entry to a dropdown list. Only single text entries are allowed
+ *
+ * \param b IN the widget
+ * \param text IN string to add
+ * \return describe the return value
+ */
+
+void wDropListAddValue(
+ wList_p b,
+ char *text,
+ wListItem_p data)
+{
+ GtkTreeIter iter;
+
+ assert(b != NULL);
+ assert(text != NULL);
+
+ gtk_list_store_append(b->listStore, &iter); // append new row to tree store
+
+ gtk_list_store_set(b->listStore, &iter,
+ LISTCOL_TEXT, text,
+ LISTCOL_DATA, (void *)data,
+ -1);
+}
+
+/**
+ * Set the value to the entry field of a droplist
+ * \param bl IN
+ * \param val IN
+ */
+
+void wListSetValue(
+ wList_p bl,
+ const char * val)
+{
+ assert(bl->listStore!=NULL);
+
+ bl->recursion++;
+
+ if (bl->type == B_DROPLIST) {
+ bl->editted = TRUE;
+ gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(bl->widget))), val);
+
+ if (bl->action) {
+ bl->action(-1, val, 0, bl->data, NULL);
+ }
+ } else {
+ assert(FALSE);
+ }
+
+ bl->recursion--;
+}
+
+/**
+ * Makes the <val>th entry (0-origin) the current selection.
+ * If <val> if '-1' then no entry is selected.
+ *
+ * \param b IN the widget
+ * \param val IN the index
+ *
+ * \todo it seems BL_NONE is not used in current code, check and clean up
+ */
+
+void wDropListSetIndex(wList_p b, int val)
+{
+ if ((b->option&BL_NONE)!=0 && val < 0) {
+ gtk_combo_box_set_active(GTK_COMBO_BOX(b->widget), -1);
+ } else {
+ gtk_combo_box_set_active(GTK_COMBO_BOX(b->widget), val);
+ }
+}
+
+/**
+ * Set the values for a row in the droplist
+ *
+ * \param b IN drop list widget
+ * \param row IN index
+ * \param labelStr IN new text
+ * \param bm IN ignored
+ * \param itemData IN ignored
+ * \return
+ */
+
+wBool_t wDropListSetValues(
+ wList_p b,
+ wIndex_t row,
+ const char * labelStr,
+ wIcon_p bm,
+ void *itemData)
+{
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(b->listStore), &iter, NULL,
+ row)) {
+ gtk_list_store_set(b->listStore,
+ &iter,
+ LISTCOL_TEXT, labelStr,
+ -1);
+ return (TRUE);
+ } else {
+ return (FALSE);
+ }
+}
+
+/**
+ * Signal handler for the "changed"-signal in drop list's entry field.
+ * Get the entered text and calls the 'action' for handling of entered
+ * value.
+ * *
+ * \param entry IN entry field of the droplist
+ * \param data IN the drop list handle
+ * \return
+ */
+
+static void DropListEntryEntered(
+ GtkEntry * entry,
+ gpointer userData)
+{
+ const gchar * text;
+
+ text = gtk_entry_get_text(entry);
+
+ if (text && *text != '\0') {
+ gchar *copyOfText = g_strdup(text);
+ ((wList_p)userData)->editted = TRUE;
+ ((wList_p)userData)->action(-1, copyOfText, 1, ((wList_p)userData)->data, NULL);
+ g_free((gpointer)copyOfText);
+ } else {
+ wBeep();
+ }
+}
+
+/**
+ * Signal handler for the "changed"-signal in drop list. Gets the selected
+ * text and determines the selected row in the tree model.
+ *
+ * \param comboBox IN the combo_box
+ * \param data IN the drop list handle
+ * \return
+ */
+
+static int DropListSelectChild(
+ GtkComboBox * comboBox,
+ gpointer data)
+{
+ wList_p bl = (wList_p)data;
+ GtkTreeIter iter;
+
+ wIndex_t inx = 0;
+ gchar *string;
+ wListItem_p addData;
+
+ if (bl->recursion) {
+ return 0;
+ }
+
+ bl->editted = FALSE;
+
+ /* Obtain currently selected item from combo box.
+ * If nothing is selected, do nothing. */
+ if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(comboBox), &iter)) {
+ GtkTreeModel *model;
+
+ /* Obtain data model from combo box. */
+ model = gtk_combo_box_get_model(comboBox);
+
+ /* get the selected row */
+ string = gtk_tree_model_get_string_from_iter(model,
+ &iter);
+ inx = atoi(string);
+ g_free(string);
+
+ /* Obtain string from model. */
+ gtk_tree_model_get(model, &iter,
+ LISTCOL_TEXT, &string,
+ LISTCOL_DATA, (void *)&addData,
+ -1);
+
+ } else {
+ return 0;
+ }
+
+ /* selection changed, store new selections and call back */
+ if (bl->last != inx) {
+
+ bl->last = inx;
+
+ if (bl->valueP) {
+ *bl->valueP = inx;
+ }
+
+ /* selection changed -> callback */
+ if (string && bl->action) {
+ bl->action(inx, string, 1, bl->data, addData->itemData);
+ }
+ }
+
+ g_free(string);
+ return 1;
+}
+
+/**
+ * Create a droplist for a given liststore
+ *
+ * \param ls IN list store for dropbox
+ * \param editable IN droplist with entry field
+ * \returns the newly created widget
+ */
+
+GtkWidget *
+wlibNewDropList(GtkListStore *ls, int editable)
+{
+ GtkWidget *widget;
+
+ if (editable) {
+ widget = gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(ls));
+ } else {
+ widget = gtk_combo_box_new_with_model(GTK_TREE_MODEL(ls));
+ }
+
+ return (widget);
+}
+
+/**
+ * Create a drop down list. The drop down is created and intialized with the supplied values.
+ *
+ * \param IN parent Parent window
+ * \param IN x, X-position
+ * \param IN y Y-position
+ * \param IN helpStr Help string
+ * \param IN labelStr Label
+ * \param IN option Options
+ * \param IN number Number of displayed entries
+ * \param IN width Width
+ * \param IN valueP Selected index
+ * \param IN action Callback
+ * \param IN data Context
+ */
+
+wList_p wDropListCreate(
+ wWin_p parent,
+ wPos_t x,
+ wPos_t y,
+ const char * helpStr,
+ const char * labelStr,
+ long option,
+ long number,
+ wPos_t width,
+ long *valueP,
+ wListCallBack_p action,
+ void *data)
+{
+ wList_p b;
+
+ b = (wList_p)wlibAlloc(parent, B_DROPLIST, x, y, labelStr, sizeof *b, data);
+ b->option = option;
+ b->number = number;
+ b->count = 0;
+ b->last = -1;
+ b->valueP = valueP;
+ b->action = action;
+ b->listX = b->realX;
+ b->colCnt = 0;
+ b->colWidths = NULL;
+ b->colRightJust = NULL;
+ b->editable = ((option & BL_EDITABLE) != 0);
+
+ assert(width != 0);
+
+ wlibComputePos((wControl_p)b);
+
+
+ // create tree store for storing the contents
+ b->listStore = wlibNewListStore(DROPLIST_TEXTCOLUMNS);
+
+ if (!b->listStore) {
+ abort();
+ }
+
+ // create the droplist
+ b->widget = wlibNewDropList(b->listStore,
+ option & BL_EDITABLE);
+
+ if (b->widget == 0) {
+ abort();
+ }
+
+ g_object_unref(G_OBJECT(b->listStore));
+
+ wlibDropListAddColumns(b->widget, DROPLIST_TEXTCOLUMNS);
+
+ gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(b->widget),
+ LISTCOL_TEXT);
+
+ // combo's style
+ gtk_rc_parse_string("style \"my-style\" { GtkComboBox::appears-as-list = 1 } widget \"*.mycombo\" style \"my-style\" ");
+ gtk_widget_set_name(b->widget,"mycombo");
+
+ g_signal_connect(GTK_OBJECT(b->widget), "changed",
+ G_CALLBACK(DropListSelectChild), b);
+
+ if (option & BL_EDITABLE) {
+ g_signal_connect(gtk_bin_get_child(GTK_BIN(b->widget)),
+ "changed",
+ G_CALLBACK(DropListEntryEntered),
+ b);
+ }
+
+ gtk_widget_set_size_request(b->widget, width, -1);
+
+ gtk_fixed_put(GTK_FIXED(parent->widget), b->widget, b->realX, b->realY);
+ wlibControlGetSize((wControl_p)b);
+
+ if (labelStr) {
+ b->labelW = wlibAddLabel((wControl_p)b, labelStr);
+ }
+
+ gtk_widget_show(b->widget);
+ wlibAddButton((wControl_p)b);
+ wlibAddHelpString(b->widget, helpStr);
+
+ return b;
+}
+
diff --git a/app/wlib/gtklib/dynarr.h b/app/wlib/gtklib/dynarr.h
index 13c0ede..2adf115 100644
--- a/app/wlib/gtklib/dynarr.h
+++ b/app/wlib/gtklib/dynarr.h
@@ -17,6 +17,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+
+#ifndef DYNARR_H_SEEN
+#define DYNARR_H_SEEN
+
typedef struct {
int cnt;
int max;
@@ -47,3 +51,4 @@ typedef struct {
abort(); \
} \
(DA).cnt = 0; }
+#endif /* DYNARR_H_SEEN */
diff --git a/app/wlib/gtklib/filesel.c b/app/wlib/gtklib/filesel.c
index 4b92389..ca30c7f 100644
--- a/app/wlib/gtklib/filesel.c
+++ b/app/wlib/gtklib/filesel.c
@@ -28,6 +28,12 @@
#include <unistd.h>
#include <string.h>
+#define GTK_DISABLE_SINGLE_INCLUDES
+#define GDK_DISABLE_DEPRECATED
+#define GTK_DISABLE_DEPRECATED
+#define GSEAL_ENABLE
+
+#include <gtk/gtk.h>
#include "gtkint.h"
#include "i18n.h"
@@ -71,9 +77,6 @@ struct wFilSel_t * wFilSelCreate(
void * data )
{
struct wFilSel_t *fs;
- int count;
- char * cp;
- GtkFileFilter *filter;
fs = (struct wFilSel_t*)malloc(sizeof *fs);
if (!fs)
@@ -88,9 +91,10 @@ struct wFilSel_t * wFilSelCreate(
fs->data = data;
if (pattList) {
+ char * cp = strdup(pattList);
+ int count = 0;
+
//create filters for the passed filter list
- cp = strdup(pattList);
- count = 0;
// names and patterns are separated by |
cp = strtok( cp, "|" );
while ( cp && count < (MAX_ALLOWEDFILTERS - 1)) {
@@ -130,15 +134,9 @@ int wFilSelect( struct wFilSel_t * fs, const char * dirName )
char name[1024];
char *host;
char *file;
- char *namePart;
int i;
- GSList *fileNameList;
GError *err = NULL;
- GtkFileFilter *activeFilter;
-
- char **fileNames;
-
- char * cp;
+
if (fs->window == NULL) {
fs->window = gtk_file_chooser_dialog_new( fs->title,
GTK_WINDOW( fs->parent->gtkwin ),
@@ -164,20 +162,25 @@ int wFilSelect( struct wFilSel_t * fs, const char * dirName )
}
strcpy( name, dirName );
- cp = name+strlen(name);
- if (cp[-1] != '/') {
- *cp++ = '/';
- *cp = 0;
- }
- if( fs->mode == FS_SAVE )
- gtk_file_chooser_set_current_name( GTK_FILE_CHOOSER(fs->window), name );
+ if( fs->mode == FS_SAVE )
+ gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(fs->window), name );
+ // Add a current folder and a shortcut to it for Load/import dialogs
+ if( fs->mode == FS_LOAD ) {
+ gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(fs->window), name );
+ gtk_file_chooser_add_shortcut_folder( GTK_FILE_CHOOSER(fs->window), name, NULL );
+ }
+
if( gtk_dialog_run( GTK_DIALOG( fs->window )) == GTK_RESPONSE_ACCEPT ) {
+ char **fileNames;
+ GSList *fileNameList;
fileNameList = gtk_file_chooser_get_uris( GTK_FILE_CHOOSER(fs->window) );
fileNames = calloc( sizeof(char *), g_slist_length (fileNameList) );
for (i=0; i < g_slist_length (fileNameList); i++ ) {
+ char *namePart;
+
file = g_filename_from_uri( g_slist_nth_data( fileNameList, i ), &host, &err );
// check for presence of file extension
@@ -205,7 +208,7 @@ int wFilSelect( struct wFilSel_t * fs, const char * dirName )
}
free( fileNames );
g_slist_free (fileNameList);
- }
+ }
gtk_widget_hide( GTK_WIDGET( fs->window ));
return 1;
diff --git a/app/wlib/gtklib/font.c b/app/wlib/gtklib/font.c
new file mode 100644
index 0000000..c54f7de
--- /dev/null
+++ b/app/wlib/gtklib/font.c
@@ -0,0 +1,403 @@
+/** \file font.c
+ * Font selection and loading.
+ */
+
+/* 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 <stdlib.h>
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#define GTK_DISABLE_SINGLE_INCLUDES
+#define GDK_DISABLE_DEPRECATED
+#define GTK_DISABLE_DEPRECATED
+#define GSEAL_ENABLE
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "wlib.h"
+#include "gtkint.h"
+#include "i18n.h"
+
+/*
+ * Macro for debug purposes. Possible debug macro values:
+ *
+ * 0 - no messages to console (use this value when building in release mode)
+ * 1 - send errors
+ * 2 - send details
+ * 3 - send more details
+ */
+#define WLIB_FONT_DEBUG 0
+
+static gchar sampleText[] = "AbCdE0129!@$&()[]{}";
+
+static GtkWidget *fontSelectionDialog;
+
+
+/*****************************************************************************
+ * FONT HANDLERS
+ */
+
+#define FW_MEDIUM (0)
+#define FW_BOLD (1)
+#define FS_REGULAR (0)
+#define FS_ITALIC (1)
+
+/* absoluteFontSize was introduced to keep the font size information synchron
+ * between the Dt.size of ctext.c and it's drop list on the status bar and
+ * the font size coming from the gtk font dialog which is located in this file */
+int absoluteFontSize = 18;
+
+struct wFont_t {
+ PangoFontDescription *fontDescription;
+};
+
+static wFont_p standardFonts[F_HELV-F_TIMES+1][2][2];
+static wFont_p curFont = NULL;
+
+/**
+ * Callback for font selection dialog
+ *
+ * \param fontSelectionDialog IN dialog
+ * \param response IN response code from dialog
+ * \param data IN unused
+ * \return
+ */
+
+static void fontSelectionDialogCallback(GtkFontSelectionDialog
+ *fontSelectionDialog, gint response, gpointer data)
+{
+ if (response == GTK_RESPONSE_APPLY || response == GTK_RESPONSE_OK) {
+ gchar *fontName;
+
+ fontName = gtk_font_selection_dialog_get_font_name(fontSelectionDialog);
+ wPrefSetString("font", "name", fontName);
+ pango_font_description_free(curFont->fontDescription);
+ curFont->fontDescription = pango_font_description_from_string(fontName);
+ absoluteFontSize = (pango_font_description_get_size(
+ curFont->fontDescription))/PANGO_SCALE;
+#if WLIB_FONT_DEBUG >= 2
+ fprintf(stderr, "new font selection:\n");
+ fprintf(stderr, " font name \"%s\"\n", fontName);
+ fprintf(stderr, " font size is %d\n",
+ pango_font_description_get_size(curFont->fontDescription)/PANGO_SCALE);
+ fprintf(stderr, " font size is absolute %d\n",
+ pango_font_description_get_size_is_absolute(curFont->fontDescription));
+#endif
+ g_free(fontName);
+ }
+
+ if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_CANCEL) {
+ gtk_widget_hide(GTK_WIDGET(fontSelectionDialog));
+ }
+}
+
+static wBool_t fontInitted = FALSE;
+
+static wBool_t fontInit()
+{
+ const char *fontNames[] = {
+ "times 18",
+ "times italic 18",
+ "times bold 18",
+ "times bold italic 18",
+ "helvetica 18",
+ "helvetica oblique 18",
+ "helvetica bold 18",
+ "helvetica bold oblique 18",
+ };
+ int s = 0;
+ int i, j, k;
+
+ for (i = F_TIMES; i <= F_HELV; ++i) {
+ for (j = FW_MEDIUM; j <= FW_BOLD; ++j) {
+ for (k = FS_REGULAR; k <= FS_ITALIC; ++k) {
+ PangoFontDescription *fontDescription = pango_font_description_from_string(
+ fontNames[s++]);
+ wFont_p standardFont = (wFont_p) malloc(sizeof(struct wFont_t));
+ standardFont->fontDescription = fontDescription;
+ standardFonts[i-F_TIMES][j][k] = standardFont;
+ }
+ }
+ }
+
+ if (curFont == NULL) {
+ curFont = (wFont_p) malloc(sizeof(struct wFont_t));
+
+ if (curFont == NULL) {
+ return FALSE;
+ }
+
+ const char *fontName = wPrefGetString("font", "name");
+ curFont->fontDescription = pango_font_description_from_string(
+ fontName ? fontName : "helvetica 18");
+ absoluteFontSize = (int) PANGO_PIXELS(pango_font_description_get_size(
+ curFont->fontDescription));
+ }
+
+ fontInitted = TRUE;
+ return TRUE;
+}
+
+
+static double fontFactor = 1.0;
+
+#define FONTSIZE_TO_PANGOSIZE(fs) ((gint) ((fs) * (fontFactor) + .5))
+
+/**
+ * Create a Pango layout with a specified font and font size
+ *
+ * \param widget IN
+ * \param cairo IN cairo context
+ * \param fp IN font
+ * \param fs IN size
+ * \param s IN ???
+ * \param width_p OUT width of layout
+ * \param height_p OUT height of layout
+ * \param ascent_p OUT ascent of layout
+ * \param descent_p OUT descent of layout
+ * \return the created Pango layout
+ */
+
+PangoLayout *wlibFontCreatePangoLayout(GtkWidget *widget,
+ void *cairo,
+ wFont_p fp,
+ wFontSize_t fs,
+ const char *s,
+ int *width_p,
+ int *height_p,
+ int *ascent_p,
+ int *descent_p)
+{
+ if (!fontInitted) {
+ fontInit();
+ }
+
+ PangoLayout *layout = NULL;
+ gchar *utf8 = wlibConvertInput(s);
+ /* RPH -- pango_cairo_create_layout() is missing in CentOS 4.8.
+ CentOS 4.8 only has GTK 2.4.13 and Pango 1.6.0 and does not have
+ libpangocairo at all.
+ pango_cairo_create_layout() was introduced with Pango 1.10. */
+#if PANGO_VERSION_MAJOR >= 1 && PANGO_VERSION_MINOR >= 10
+
+ if (cairo != NULL) {
+ layout = pango_cairo_create_layout((cairo_t *) cairo);
+ pango_layout_set_text(layout, utf8, -1);
+ } else
+#endif
+ layout = gtk_widget_create_pango_layout(widget, utf8);
+
+ PangoFontDescription *fontDescription = (fp ? fp : curFont)->fontDescription;
+ PangoContext *context;
+ PangoFontMetrics *metrics;
+ /* set attributes */
+ pango_font_description_set_size(fontDescription,
+ FONTSIZE_TO_PANGOSIZE(fs) * PANGO_SCALE);
+ pango_layout_set_font_description(layout, fontDescription);
+ /* get layout measures */
+ pango_layout_get_pixel_size(layout, width_p, height_p);
+ context = gtk_widget_get_pango_context(widget);
+ metrics = pango_context_get_metrics(context, fontDescription,
+ pango_context_get_language(context));
+ *ascent_p = PANGO_PIXELS(pango_font_metrics_get_ascent(metrics));
+ *descent_p = PANGO_PIXELS(pango_font_metrics_get_descent(metrics));
+ pango_font_metrics_unref(metrics);
+#if WLIB_FONT_DEBUG >= 3
+ fprintf(stderr, "font layout created:\n");
+ fprintf(stderr, " widget: %p\n", widget);
+ //fprintf(stderr, " font description:%p\n", fp);
+ fprintf(stderr, " font size: %f\n", fs);
+ fprintf(stderr, " layout text: \"%s\" (utf8)\n", utf8);
+ fprintf(stderr, " layout width: %d\n", *width_p);
+ fprintf(stderr, " layout height: %d\n", *height_p);
+ fprintf(stderr, " layout ascent: %d (pixels)\n", *ascent_p);
+ fprintf(stderr, " layout descent: %d (pixels)\n", *descent_p);
+#endif
+ return layout;
+}
+
+/**
+ * Destroy a previously allocated Pango layout
+ * \return
+ */
+
+void wlibFontDestroyPangoLayout(PangoLayout *layout)
+{
+ g_object_unref(G_OBJECT(layout));
+}
+
+/**
+ * Initialize font data
+ * \return
+ */
+
+void wInitializeFonts()
+{
+ if (!fontInitted) {
+ fontInit();
+ }
+}
+
+/**
+ * Initialize and run the font dialog
+ *
+ * \param title IN dialog box title
+ * \return
+ */
+
+void wSelectFont(
+ const char * title)
+{
+ if (!fontInitted) {
+ fontInit();
+ }
+
+ if (fontSelectionDialog == NULL) {
+ fontSelectionDialog = gtk_font_selection_dialog_new(_("Font Select"));
+ gtk_window_set_position(GTK_WINDOW(fontSelectionDialog), GTK_WIN_POS_MOUSE);
+ gtk_window_set_modal(GTK_WINDOW(fontSelectionDialog), TRUE);
+ gtk_font_selection_dialog_set_preview_text(GTK_FONT_SELECTION_DIALOG(
+ fontSelectionDialog), sampleText);
+ g_signal_connect(G_OBJECT(fontSelectionDialog), "response",
+ G_CALLBACK(fontSelectionDialogCallback), NULL);
+ g_signal_connect(G_OBJECT(fontSelectionDialog), "destroy",
+ G_CALLBACK(gtk_widget_destroyed), &fontSelectionDialog);
+ }
+
+ gtk_window_set_title(GTK_WINDOW(fontSelectionDialog), title);
+
+ if (curFont != NULL) {
+ gchar *fontName;
+
+ /* the curFont description contains the latest font info
+ * which is depended on the current scale
+ * overwrite it with the absoluteFontSize */
+ pango_font_description_set_size(curFont->fontDescription,
+ FONTSIZE_TO_PANGOSIZE(absoluteFontSize) * PANGO_SCALE);
+ fontName = pango_font_description_to_string(curFont->fontDescription);
+ gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(
+ fontSelectionDialog), fontName);
+ g_free(fontName);
+ }
+
+ gtk_widget_show(fontSelectionDialog);
+}
+
+/**
+ * Get the current font
+ *
+ * \return describe the return value
+ */
+
+static wFont_p wlibSelectedFont(void)
+{
+ if (!fontInitted) {
+ fontInit();
+ }
+
+ return curFont;
+}
+
+/**
+ * Get the default font size
+ *
+ * \return describe the return value
+ */
+
+wFontSize_t wSelectedFontSize(void)
+{
+ if (!fontInitted) {
+ fontInit();
+ }
+
+#if WLIB_FONT_DEBUG >= 3
+ fprintf(stderr, "the font size of current font description is: %d\n",
+ pango_font_description_get_size(curFont->fontDescription)/PANGO_SCALE);
+ fprintf(stderr, "the font size of absoluteFontSize is: %d\n",absoluteFontSize);
+#endif
+ return absoluteFontSize;
+}
+
+/**
+ * Set the default font size
+ *
+ * \param size IN font size
+ * \return describe the return value
+ */
+
+void wSetSelectedFontSize(int size)
+{
+ absoluteFontSize = (wFontSize_t)size;
+}
+
+/**
+ * get the Pango font description as a string from a font definition.
+ * If the font definition is NULL, a default font is return. This is
+ * the current font if one is set. If not the first font from the font
+ * list is returned.
+ *
+ * \param fp IN the font definition
+ * \return the font description
+ */
+
+const char *wlibFontTranslate(wFont_p fp)
+{
+ static gchar *fontName = NULL;
+
+ if (fontName != NULL) {
+ g_free(fontName);
+ }
+
+ if (!fontInitted) {
+ fontInit();
+ }
+
+ if (fp == NULL) {
+ fp = wlibSelectedFont();
+ }
+
+ if (fp == NULL) {
+ fp = standardFonts[0][FW_MEDIUM][FS_REGULAR];
+ }
+
+ fontName = pango_font_description_to_string(fp->fontDescription);
+#if WLIB_FONT_DEBUG >= 2
+ fprintf(stderr, "font translation: ");
+ fprintf(stderr, " \"%s\"\n", fontName);
+#endif
+ return (const char *) fontName;
+}
+
+/**
+ * Return description for one of the standard fonts
+ *
+ * \return
+ */
+
+wFont_p wStandardFont(int face, wBool_t bold, wBool_t italic)
+{
+ if (!fontInitted) {
+ fontInit();
+ }
+
+ return standardFonts[face-F_TIMES][bold][italic];
+}
diff --git a/app/wlib/gtklib/gtkbitmap.c b/app/wlib/gtklib/gtkbitmap.c
deleted file mode 100644
index 8f85951..0000000
--- a/app/wlib/gtklib/gtkbitmap.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/wlib/gtklib/gtkbitmap.c,v 1.5 2009-09-27 04:28:03 dspagnol Exp $
- */
-/* XTrkCad - Model Railroad CAD
- * Copyright (C) 2009 Daniel Spagnol
- *
- * 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 <stdlib.h>
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-#include <unistd.h>
-#include <string.h>
-#include <math.h>
-#include <stdlib.h>
-
-#include "gtkint.h"
-
-
-struct wBitmap_t {
- WOBJ_COMMON
-};
-
-/**
- * Create a static control for displaying a bitmap.
- *
- * \param parent IN parent window
- * \param x, y IN position in parent window
- * \param option IN ignored for now
- * \param iconP IN icon to use
- * \return the control
- */
-
-wControl_p
-wBitmapCreate( wWin_p parent, wPos_t x, wPos_t y, long options, wIcon_p iconP )
-{
- wBitmap_p bt;
- GdkPixbuf *pixbuf;
-
- bt = gtkAlloc( parent, B_BITMAP, x, y, NULL, sizeof *bt, NULL );
- bt->w = iconP->w;
- bt->h = iconP->h;
- bt->option = options;
-
- /*
- * Depending on the platform, parent->widget->window might still be null
- * at this point. The window allocation should be forced before creating
- * the pixmap.
- */
- if ( parent->widget->window == NULL )
- gtk_widget_realize( parent->widget ); /* force allocation, if pending */
-
- pixbuf = gdk_pixbuf_new_from_xpm_data( (const char**)iconP->bits );
- GtkWidget *image = gtk_image_new_from_pixbuf( pixbuf );
-
- gtk_widget_show( image );
-
- bt->widget = gtk_fixed_new();
- gtk_container_add( GTK_CONTAINER(bt->widget), image );
- gtk_widget_show( bt->widget );
-
- gtkComputePos( (wControl_p)bt );
- gtkControlGetSize( (wControl_p)bt );
- gtk_fixed_put( GTK_FIXED( parent->widget ), bt->widget, bt->realX, bt->realY );
-
- g_object_unref( pixbuf );
-
- return( (wControl_p)bt );
-}
-
diff --git a/app/wlib/gtklib/gtkbutton.c b/app/wlib/gtklib/gtkbutton.c
deleted file mode 100644
index 7780535..0000000
--- a/app/wlib/gtklib/gtkbutton.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/** \file gtkbutton.c
- * Toolbar button creation and handling
- *
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/wlib/gtklib/gtkbutton.c,v 1.8 2009-10-03 04:49:01 dspagnol Exp $
- */
-
-/* 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 <stdlib.h>
-#include <gtk/gtk.h>
-#include <gdk/gdk.h>
-
-#include "gtkint.h"
-#include "i18n.h"
-
-#define MIN_BUTTON_WIDTH (80)
-
-/*
- *****************************************************************************
- *
- * Simple Buttons
- *
- *****************************************************************************
- */
-
-struct wButton_t {
- WOBJ_COMMON
- GtkLabel * labelG;
- GtkWidget * imageG;
- wButtonCallBack_p action;
- int busy;
- int recursion;
- };
-
-
-void wButtonSetBusy( wButton_p bb, int value ) {
- bb->recursion++;
- gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(bb->widget), value );
- bb->recursion--;
- bb->busy = value;
-}
-
-
-void gtkSetLabel(
- GtkWidget *widget,
- long option,
- const char * labelStr,
- GtkLabel * * labelG,
- GtkWidget * * imageG )
-{
- wIcon_p bm;
- GdkPixbuf *pixbuf;
-
- GdkPixmap * pixmap;
- GdkBitmap * mask;
-
- GtkWidget * hbox;
- if (widget == 0) abort();
- if (labelStr){
- if (option&BO_ICON) {
- bm = (wIcon_p)labelStr;
-
- // for XPM files use the pixbuf functions
- if( bm->gtkIconType == gtkIcon_pixmap ) {
- pixbuf = gdk_pixbuf_new_from_xpm_data( (const char**)bm->bits );
- if (*imageG==NULL) {
- *imageG = gtk_image_new_from_pixbuf( pixbuf );
- gtk_container_add( GTK_CONTAINER( widget ), *imageG );
- gtk_widget_show( *imageG );
- } else {
- gtk_image_set_from_pixbuf( GTK_IMAGE(*imageG), pixbuf );
- }
- g_object_unref( pixbuf );
- } else {
- // otherwise use the conversion to XPM
- /** \todo { Should use the way via a pixbuf as well } */
- pixmap = gtkMakeIcon( widget, bm, &mask );
- if (*imageG==NULL) {
- *imageG = gtk_image_new_from_pixmap( pixmap, NULL );
- gtk_widget_show( *imageG );
- gtk_container_add( GTK_CONTAINER( widget ), *imageG );
- } else {
- gtk_image_set_from_pixmap( GTK_IMAGE(*imageG), pixmap, NULL );
- }
- gdk_pixmap_unref( pixmap );
- gdk_bitmap_unref( mask );
- }
- } else {
- if (*labelG==NULL) {
- *labelG = (GtkLabel*)gtk_label_new( gtkConvertInput(labelStr) );
- gtk_container_add( GTK_CONTAINER(widget), (GtkWidget*)*labelG );
- gtk_widget_show( (GtkWidget*)*labelG );
- } else {
- gtk_label_set( *labelG, gtkConvertInput(labelStr) );
- }
- }
- }
-}
-
-void wButtonSetLabel( wButton_p bb, const char * labelStr) {
- gtkSetLabel( bb->widget, bb->option, labelStr, &bb->labelG, &bb->imageG );
-}
-
-
-
-void gtkButtonDoAction(
- wButton_p bb )
-{
- if (bb->action)
- bb->action( bb->data );
-}
-
-
-static void pushButt(
- GtkWidget *widget,
- gpointer value )
-{
- wButton_p b = (wButton_p)value;
- if (debugWindow >= 2) printf("%s button pushed\n", b->labelStr?b->labelStr:"No label" );
- if (b->recursion)
- return;
- if (b->action)
- b->action(b->data);
- if (!b->busy) {
- b->recursion++;
- gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(b->widget), FALSE );
- b->recursion--;
- }
-}
-
-wButton_p wButtonCreate(
- wWin_p parent,
- wPos_t x,
- wPos_t y,
- const char * helpStr,
- const char * labelStr,
- long option,
- wPos_t width,
- wButtonCallBack_p action,
- void * data )
-{
- wButton_p b;
- b = gtkAlloc( parent, B_BUTTON, x, y, labelStr, sizeof *b, data );
- b->option = option;
- b->action = action;
- gtkComputePos( (wControl_p)b );
-
- b->widget = gtk_toggle_button_new();
-
- gtk_signal_connect (GTK_OBJECT(b->widget), "clicked",
- GTK_SIGNAL_FUNC(pushButt), b );
- if (width > 0)
- gtk_widget_set_size_request( b->widget, width, -1 );
- wButtonSetLabel( b, labelStr );
-
- gtk_fixed_put( GTK_FIXED(parent->widget), b->widget, b->realX, b->realY );
- if (option & BB_DEFAULT) {
- GTK_WIDGET_SET_FLAGS( b->widget, GTK_CAN_DEFAULT );
- gtk_widget_grab_default( b->widget );
- gtk_window_set_default( GTK_WINDOW(parent->gtkwin), b->widget );
- }
- gtkControlGetSize( (wControl_p)b );
- if (width == 0 && b->w < MIN_BUTTON_WIDTH && (b->option&BO_ICON)==0) {
- b->w = MIN_BUTTON_WIDTH;
- gtk_widget_set_size_request( b->widget, b->w, b->h );
- }
- gtk_widget_show( b->widget );
- gtkAddButton( (wControl_p)b );
- gtkAddHelpString( b->widget, helpStr );
- return b;
-}
-
-
-/*
- *****************************************************************************
- *
- * Choice Boxes
- *
- *****************************************************************************
- */
-
-struct wChoice_t {
- WOBJ_COMMON
- long *valueP;
- wChoiceCallBack_p action;
- int recursion;
- };
-
-
-static long choiceGetValue(
- wChoice_p bc )
-{
- GList * child, * children;
- long value, inx;
- if (bc->type == B_TOGGLE)
- value = 0;
- else
- value = -1;
- for ( children=child=gtk_container_children(GTK_CONTAINER(bc->widget)),inx=0; child; child=child->next,inx++ ) {
- if ( GTK_TOGGLE_BUTTON(child->data)->active ) {
- if (bc->type == B_TOGGLE) {
- value |= (1<<inx);
- } else {
- value = inx;
- }
- }
- }
- if ( children )
- g_list_free( children );
- return value;
-}
-
-EXPORT void wRadioSetValue(
- wChoice_p bc, /* Radio box */
- long value ) /* Value */
-/*
-*/
-{
- GList * child, * children;
- long inx;
- for ( children=child=gtk_container_children(GTK_CONTAINER(bc->widget)),inx=0; child; child=child->next,inx++ ) {
- if (inx == value) {
- bc->recursion++;
- gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(child->data), TRUE );
- bc->recursion--;
- }
- }
- if ( children )
- g_list_free( children );
-}
-
-
-EXPORT long wRadioGetValue(
- wChoice_p bc ) /* Radio box */
-/*
-*/
-{
- return choiceGetValue(bc);
-}
-
-
-EXPORT void wToggleSetValue(
- wChoice_p bc, /* Toggle box */
- long value ) /* Values */
-/*
-*/
-{
- GList * child, * children;
- long inx;
- bc->recursion++;
- for ( children=child=gtk_container_children(GTK_CONTAINER(bc->widget)),inx=0; child; child=child->next,inx++ ) {
- gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(child->data), (value&(1<<inx))!=0 );
- }
- if ( children )
- g_list_free( children );
- bc->recursion--;
-}
-
-
-EXPORT long wToggleGetValue(
- wChoice_p b ) /* Toggle box */
-/*
-*/
-{
- return choiceGetValue(b);
-}
-
-
-static int pushChoice(
- GtkWidget *widget,
- gpointer b )
-{
- wChoice_p bc = (wChoice_p)b;
- long value = choiceGetValue( bc );
- if (debugWindow >= 2) printf("%s choice pushed = %ld\n", bc->labelStr?bc->labelStr:"No label", value );
- if ( bc->type == B_RADIO && !(GTK_TOGGLE_BUTTON(widget))->active )
- return 1;
- if (bc->recursion)
- return 1;
- if (bc->valueP)
- *bc->valueP = value;
- if (bc->action)
- bc->action( value, bc->data);
- return 1;
-}
-
-
-static void choiceRepaint(
- wControl_p b )
-{
- wChoice_p bc = (wChoice_p)b;
- if ( GTK_WIDGET_VISIBLE( b->widget ) )
- gtkDrawBox( bc->parent, wBoxBelow, bc->realX-1, bc->realY-1, bc->w+1, bc->h+1 );
-}
-
-
-EXPORT wChoice_p wRadioCreate(
- wWin_p parent, /* Parent window */
- wPos_t x, /* X-position */
- wPos_t y, /* Y-position */
- const char * helpStr, /* Help string */
- const char * labelStr, /* Label */
- long option, /* Options */
- const char **labels, /* Labels */
- long *valueP, /* Selected value */
- wChoiceCallBack_p action, /* Callback */
- void *data ) /* Context */
-/*
-*/
-{
- wChoice_p b;
- const char ** label;
- GtkWidget *butt0=NULL, *butt;
-
- if ((option & BC_NOBORDER)==0) {
- if (x>=0)
- x++;
- else
- x--;
- if (y>=0)
- y++;
- else
- y--;
- }
- b = gtkAlloc( parent, B_RADIO, x, y, labelStr, sizeof *b, data );
- b->option = option;
- b->action = action;
- b->valueP = valueP;
- gtkComputePos( (wControl_p)b );
-
- if (option&BC_HORZ)
- b->widget = gtk_hbox_new( FALSE, 0 );
- else
- b->widget = gtk_vbox_new( FALSE, 0 );
- if (b->widget == 0) abort();
- for ( label=labels; *label; label++ ) {
- butt = gtk_radio_button_new_with_label(
- butt0?gtk_radio_button_group(GTK_RADIO_BUTTON(butt0)):NULL, _(*label) );
- if (butt0==NULL)
- butt0 = butt;
- gtk_box_pack_start( GTK_BOX(b->widget), butt, TRUE, TRUE, 0 );
- gtk_widget_show( butt );
- gtk_signal_connect (GTK_OBJECT(butt), "toggled",
- GTK_SIGNAL_FUNC( pushChoice ), b );
- gtkAddHelpString( butt, helpStr );
- }
- if (option & BB_DEFAULT) {
- GTK_WIDGET_SET_FLAGS( b->widget, GTK_CAN_DEFAULT );
- gtk_widget_grab_default( b->widget );
- /*gtk_window_set_default( GTK_WINDOW(parent->gtkwin), b->widget );*/
- }
- if (valueP)
- wRadioSetValue( b, *valueP );
-
- if ((option & BC_NOBORDER)==0) {
- if (parent->gc == NULL) {
- parent->gc = gdk_gc_new( parent->gtkwin->window );
- gdk_gc_copy( parent->gc, parent->gtkwin->style->base_gc[GTK_STATE_NORMAL] );
- parent->gc_linewidth = 0;
- gdk_gc_set_line_attributes( parent->gc, parent->gc_linewidth, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER );
- }
- b->repaintProc = choiceRepaint;
- b->w += 2;
- b->h += 2;
- }
-
- gtk_fixed_put( GTK_FIXED(parent->widget), b->widget, b->realX, b->realY );
- gtkControlGetSize( (wControl_p)b );
- if (labelStr)
- b->labelW = gtkAddLabel( (wControl_p)b, labelStr );
- gtk_widget_show( b->widget );
- gtkAddButton( (wControl_p)b );
- return b;
-}
-
-wChoice_p wToggleCreate(
- wWin_p parent, /* Parent window */
- wPos_t x, /* X-position */
- wPos_t y, /* Y-position */
- const char * helpStr, /* Help string */
- const char * labelStr, /* Label */
- long option, /* Options */
- const char **labels, /* Labels */
- long *valueP, /* Selected value */
- wChoiceCallBack_p action, /* Callback */
- void *data ) /* Context */
-/*
-*/
-{
- wChoice_p b;
- const char ** label;
- GtkWidget *butt;
-
- if ((option & BC_NOBORDER)==0) {
- if (x>=0)
- x++;
- else
- x--;
- if (y>=0)
- y++;
- else
- y--;
- }
- b = gtkAlloc( parent, B_TOGGLE, x, y, labelStr, sizeof *b, data );
- b->option = option;
- b->action = action;
- gtkComputePos( (wControl_p)b );
-
- if (option&BC_HORZ)
- b->widget = gtk_hbox_new( FALSE, 0 );
- else
- b->widget = gtk_vbox_new( FALSE, 0 );
- if (b->widget == 0) abort();
- for ( label=labels; *label; label++ ) {
- butt = gtk_check_button_new_with_label(_(*label));
- gtk_box_pack_start( GTK_BOX(b->widget), butt, TRUE, TRUE, 0 );
- gtk_widget_show( butt );
- gtk_signal_connect (GTK_OBJECT(butt), "toggled",
- GTK_SIGNAL_FUNC( pushChoice ), b );
- gtkAddHelpString( butt, helpStr );
- }
- if (valueP)
- wToggleSetValue( b, *valueP );
-
- if ((option & BC_NOBORDER)==0) {
- if (parent->gc == NULL) {
- parent->gc = gdk_gc_new( parent->gtkwin->window );
- gdk_gc_copy( parent->gc, parent->gtkwin->style->base_gc[GTK_STATE_NORMAL] );
- parent->gc_linewidth = 0;
- gdk_gc_set_line_attributes( parent->gc, parent->gc_linewidth, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER );
- }
- b->repaintProc = choiceRepaint;
- b->w += 2;
- b->h += 2;
- }
-
- gtk_fixed_put( GTK_FIXED(parent->widget), b->widget, b->realX, b->realY );
- gtkControlGetSize( (wControl_p)b );
- if (labelStr)
- b->labelW = gtkAddLabel( (wControl_p)b, labelStr );
- gtk_widget_show( b->widget );
- gtkAddButton( (wControl_p)b );
- return b;
-}
diff --git a/app/wlib/gtklib/gtkcolor.c b/app/wlib/gtklib/gtkcolor.c
deleted file mode 100644
index cf17199..0000000
--- a/app/wlib/gtklib/gtkcolor.c
+++ /dev/null
@@ -1,476 +0,0 @@
-/** \file gtkcolor.c
- * code for the color selection dialog and color button
- *
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/wlib/gtklib/gtkcolor.c,v 1.3 2007-11-24 19:48:21 tshead Exp $
- */
-
-/* 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 <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-#include <unistd.h>
-#include <stdlib.h>
-
-#include "gtkint.h"
-
-#include "square10.bmp"
-
-EXPORT wDrawColor wDrawColorWhite;
-EXPORT wDrawColor wDrawColorBlack;
-
-#define RGB(R,G,B) ( ((long)((R)&0xFF)<<16) | ((long)((G)&0xFF)<<8) | ((long)((B)&0xFF)) )
-
-#define MAX_COLOR_DISTANCE (3)
-
-typedef struct {
- unsigned char red;
- unsigned char green;
- unsigned char blue;
- GdkColor normalColor;
- GdkColor invertColor;
- long rgb;
- int colorChar;
- } colorMap_t;
-static GArray *colorMap_garray = NULL; // Change to use glib array
-
-static colorMap_t colorMap[] = {
- { 255, 255, 255 }, /* White */
- { 0, 0, 0 }, /* Black */
- { 255, 0, 0 }, /* Red */
- { 0, 255, 0 }, /* Green */
- { 0, 0, 255 }, /* Blue */
- { 255, 255, 0 }, /* Yellow */
- { 255, 0, 255 }, /* Purple */
- { 0, 255, 255 }, /* Aqua */
- { 128, 0, 0 }, /* Dk. Red */
- { 0, 128, 0 }, /* Dk. Green */
- { 0, 0, 128 }, /* Dk. Blue */
- { 128, 128, 0 }, /* Dk. Yellow */
- { 128, 0, 128 }, /* Dk. Purple */
- { 0, 128, 128 }, /* Dk. Aqua */
- { 65, 105, 225 }, /* Royal Blue */
- { 0, 191, 255 }, /* DeepSkyBlue */
- { 125, 206, 250 }, /* LightSkyBlue */
- { 70, 130, 180 }, /* Steel Blue */
- { 176, 224, 230 }, /* Powder Blue */
- { 127, 255, 212 }, /* Aquamarine */
- { 46, 139, 87 }, /* SeaGreen */
- { 152, 251, 152 }, /* PaleGreen */
- { 124, 252, 0 }, /* LawnGreen */
- { 50, 205, 50 }, /* LimeGreen */
- { 34, 139, 34 }, /* ForestGreen */
- { 255, 215, 0 }, /* Gold */
- { 188, 143, 143 }, /* RosyBrown */
- { 139, 69, 19 }, /* SaddleBrown */
- { 245, 245, 220 }, /* Beige */
- { 210, 180, 140 }, /* Tan */
- { 210, 105, 30 }, /* Chocolate */
- { 165, 42, 42 }, /* Brown */
- { 255, 165, 0 }, /* Orange */
- { 255, 127, 80 }, /* Coral */
- { 255, 99, 71 }, /* Tomato */
- { 255, 105, 180 }, /* HotPink */
- { 255, 192, 203 }, /* Pink */
- { 176, 48, 96 }, /* Maroon */
- { 238, 130, 238 }, /* Violet */
- { 160, 32, 240 }, /* Purple */
- { 16, 16, 16 }, /* Gray */
- { 32, 32, 32 }, /* Gray */
- { 48, 48, 48 }, /* Gray */
- { 64, 64, 64 }, /* Gray */
- { 80, 80, 80 }, /* Gray */
- { 96, 96, 96 }, /* Gray */
- { 112, 112, 122 }, /* Gray */
- { 128, 128, 128 }, /* Gray */
- { 144, 144, 144 }, /* Gray */
- { 160, 160, 160 }, /* Gray */
- { 176, 176, 176 }, /* Gray */
- { 192, 192, 192 }, /* Gray */
- { 208, 208, 208 }, /* Gray */
- { 224, 224, 224 }, /* Gray */
- { 240, 240, 240 }, /* Gray */
- { 0, 0, 0 } /* BlackPixel */
- };
-
-#define NUM_GRAYS (16)
-
-static GdkColormap * gtkColorMap;
-
-static char lastColorChar = '!';
-
-/*****************************************************************************
- *
- *
- *
- */
-
-
-EXPORT wDrawColor wDrawColorGray(
- int percent )
-{
- int n;
- long rgb;
- n = (percent * (NUM_GRAYS+1)) / 100;
- if ( n <= 0 )
- return wDrawColorBlack;
- else if ( n > NUM_GRAYS )
- return wDrawColorWhite;
- else {
- n = (n*256)/NUM_GRAYS;
- rgb = RGB( n, n, n );
- return wDrawFindColor( rgb );
- }
-}
-
-
-void gtkGetColorMap( void )
-{
- if (gtkColorMap)
- return;
- gtkColorMap = gtk_widget_get_colormap( gtkMainW->widget );
- return;
-}
-
-void init_colorMapValue( colorMap_t * t) {
-
- t->rgb = RGB( t->red, t->green, t->blue );
- t->normalColor.red = t->red*65535/255;
- t->normalColor.green = t->green*65535/255;
- t->normalColor.blue = t->blue*65535/255;
- gdk_color_alloc( gtkColorMap, &t->normalColor );
- t->invertColor = t->normalColor;
- t->invertColor.pixel ^= g_array_index(colorMap_garray, colorMap_t, wDrawColorWhite).normalColor.pixel;
- t->colorChar = lastColorChar++;
- if (lastColorChar >= 0x7F)
- lastColorChar = '!'+1;
- else if (lastColorChar == '"')
- lastColorChar++;
-
-}
-
-
-void init_colorMap( void )
-{
- colorMap_garray = g_array_sized_new(TRUE, TRUE, sizeof(colorMap_t), sizeof(colorMap)/sizeof(colorMap_t));
- g_array_append_vals(colorMap_garray, &colorMap, sizeof(colorMap)/sizeof(colorMap_t));
-
- int gint;
-
- for(gint=0; gint<colorMap_garray->len; gint++) {
- init_colorMapValue(&g_array_index(colorMap_garray, colorMap_t, gint));
- }
-}
-
-
-EXPORT wDrawColor wDrawFindColor(
- long rgb0 )
-{
- wDrawColor cc;
- int r0, g0, b0;
- int d0, d1;
- long rgb1;
- colorMap_t * cm_p;
-
- gtkGetColorMap();
-
- cc = wDrawColorBlack;
- r0 = (int)(rgb0>>16)&0xFF;
- g0 = (int)(rgb0>>8)&0xFF;
- b0 = (int)(rgb0)&0xFF;
- d0 = 256*3;
-
- // Initialize garray if needed
- if (colorMap_garray == NULL) {
- init_colorMap();
- }
-
- int gint;
-
- // Iterate over entire garray
- for (gint=0; gint<colorMap_garray->len; gint++) {
- cm_p = &g_array_index(colorMap_garray, colorMap_t, gint);
- rgb1 = cm_p->rgb;
- d1 = abs(r0-cm_p->red) + abs(g0-cm_p->green) + abs(b0-cm_p->blue);
- if (d1 == 0)
- return gint;
- if (d1 < d0) {
- d0 = d1;
- cc = gint;
- }
- }
- if (d0 <= MAX_COLOR_DISTANCE) {
- return cc;
- }
- // No good value - so add one
- colorMap_t tempMapValue;
- //DYNARR_APPEND( colorMap_t, colorMap_da, 10 );
- tempMapValue.red = r0;
- tempMapValue.green = g0;
- tempMapValue.blue = b0;
- init_colorMapValue(&tempMapValue);
- g_array_append_val(colorMap_garray,tempMapValue);
- return gint;
-}
-
-
-EXPORT long wDrawGetRGB(
- wDrawColor color )
-{
- gtkGetColorMap();
-
- if(colorMap_garray == NULL)
- init_colorMap();
-
- if (color < 0 || color > colorMap_garray->len)
- abort();
- colorMap_t * colorMap_e;
- colorMap_e = &g_array_index(colorMap_garray, colorMap_t, color);
- return colorMap_e->rgb;
-}
-
-
-EXPORT GdkColor* gtkGetColor(
- wDrawColor color,
- wBool_t normal )
-{
- gtkGetColorMap();
-
- if(colorMap_garray == NULL)
- init_colorMap();
-
- if (color < 0 || color > colorMap_garray->len)
- abort();
- colorMap_t * colorMap_e;
- colorMap_e = &g_array_index(colorMap_garray, colorMap_t, color);
-
- if ( normal )
- return &colorMap_e->normalColor;
- else
- return &colorMap_e->invertColor;
-}
-
-
-EXPORT int gtkGetColorChar(
- wDrawColor color )
-{
- /*gtkGetColorMap();*/
- if(colorMap_garray == NULL)
- init_colorMap();
-
- if (color < 0 || color > colorMap_garray->len)
- abort();
- colorMap_t * colorMap_e;
- colorMap_e = &g_array_index(colorMap_garray, colorMap_t, color);
- return colorMap_e->colorChar;
-}
-
-
-EXPORT int gtkMapPixel(
- long pixel )
-{
- colorMap_t * mapValue;
- int gint;
-
- if(colorMap_garray == NULL)
- init_colorMap();
-
- for (gint=0; gint<colorMap_garray->len; gint++ ) {
- mapValue = &g_array_index(colorMap_garray, colorMap_t, gint);
- if ( mapValue->normalColor.pixel == pixel ) {
- return mapValue->colorChar;
- }
- }
- mapValue = &g_array_index(colorMap_garray, colorMap_t, wDrawColorBlack);
- return mapValue->colorChar;
-}
-
-
-/*
- *****************************************************************************
- *
- * Color Selection Dialog
- *
- *****************************************************************************
- */
-
-
-static int colorSelectValid;
-static int colorSelectOk(
- GtkWidget * widget,
- GtkWidget * * window )
-{
- gtkDoModal( NULL, FALSE );
- gtk_widget_hide( GTK_WIDGET(*window) );
- colorSelectValid = TRUE;
- return FALSE;
-}
-
-
-static int colorSelectCancel(
- GtkWidget * widget,
- GtkWidget * * window )
-{
- gtkDoModal( NULL, FALSE );
- gtk_widget_hide( GTK_WIDGET(*window) );
- colorSelectValid = FALSE;
- if (widget == *window)
- /* Called by destroy event, window is gone */
- *window = NULL;
- return FALSE;
-}
-
-
-EXPORT wBool_t wColorSelect(
- const char * title,
- wDrawColor * color )
-{
- static GtkWidget * colorSelectD = NULL;
- long rgb;
- gdouble colors[4]; // Remember opacity!
-
- if (colorSelectD == NULL) {
- colorSelectD = gtk_color_selection_dialog_new( title );
- gtk_signal_connect( GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(colorSelectD)->ok_button), "clicked", (GtkSignalFunc)colorSelectOk, (gpointer)&colorSelectD );
- gtk_signal_connect( GTK_OBJECT(GTK_COLOR_SELECTION_DIALOG(colorSelectD)->cancel_button), "clicked", (GtkSignalFunc)colorSelectCancel, (gpointer)&colorSelectD );
- gtk_signal_connect( GTK_OBJECT(colorSelectD), "destroy", (GtkSignalFunc)colorSelectCancel, (gpointer)&colorSelectD );
- } else {
- gtk_window_set_title( GTK_WINDOW(colorSelectD), title );
- }
-
- colorMap_t * colorMap_e;
-
- if (!colorMap_garray) {
- init_colorMap();
- }
-
- colorMap_e = &g_array_index(colorMap_garray, colorMap_t, *color);
- colors[0] = colorMap_e->red/255.0;
- colors[1] = colorMap_e->green/255.0;
- colors[2] = colorMap_e->blue/255.0;
- colors[3] = 1.0; // Override to Fully opaque
- gtk_color_selection_set_color( GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(colorSelectD)->colorsel), colors );
- gtk_widget_show( colorSelectD );
- gtkDoModal( NULL, TRUE );
- if (colorSelectValid) {
- gtk_color_selection_get_color( GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(colorSelectD)->colorsel), colors );
- rgb = RGB( (int)(colors[0]*255), (int)(colors[1]*255), (int)(colors[2]*255) );
- * color = wDrawFindColor( rgb );
- return TRUE;
- }
- return FALSE;
-}
-
-
-/*
- *****************************************************************************
- *
- * Color Selection Button
- *
- *****************************************************************************
- */
-
-typedef struct {
- wDrawColor * valueP;
- wColorSelectButtonCallBack_p action;
- const char * labelStr;
- void * data;
- wDrawColor color;
- wButton_p button;
- } colorData_t;
-
-static void doColorButton(
- void * data )
-{
- colorData_t * cd = (colorData_t *)data;
- wDrawColor newColor;
-
- newColor = cd->color;
- if (wColorSelect( cd->labelStr, &newColor )) {
- cd->color = newColor;
- wColorSelectButtonSetColor( cd->button, newColor );
- if (cd->valueP)
- *(cd->valueP) = newColor;
- if (cd->action)
- cd->action( cd->data, newColor );
- }
-}
-
-
-void wColorSelectButtonSetColor(
- wButton_p bb,
- wDrawColor color )
-{
- wIcon_p bm;
- bm = wIconCreateBitMap( square10_width, square10_height, square10_bits, color );
- wButtonSetLabel( bb, (const char*)bm );
- ((colorData_t*)((wControl_p)bb)->data)->color = color;
-}
-
-
-wDrawColor wColorSelectButtonGetColor(
- wButton_p bb )
-{
- return ((colorData_t*)((wControl_p)bb)->data)->color;
-}
-
-/** Create the button showing the current paint color and starting the color selection dialog.
- * \param IN parent parent window
- * \param IN x x coordinate
- * \param IN Y y coordinate
- * \param IN helpStr balloon help string
- * \param IN labelStr Button label ???
- * \param IN option
- * \param IN width
- * \param IN valueP Current color ???
- * \param IN action Button callback procedure
- * \param IN data ???
- * \return bb handle for created button
- */
-
-wButton_p wColorSelectButtonCreate(
- wWin_p parent,
- wPos_t x,
- wPos_t y,
- const char * helpStr,
- const char * labelStr,
- long option,
- wPos_t width,
- wDrawColor *valueP,
- wColorSelectButtonCallBack_p action,
- void * data )
-{
- wButton_p bb;
- wIcon_p bm;
- colorData_t * cd;
- bm = wIconCreateBitMap( square10_width, square10_height, square10_bits, (valueP?*valueP:0) );
- cd = malloc( sizeof( colorData_t ));
- cd->valueP = valueP;
- cd->action = action;
- cd->data = data;
- cd->labelStr = labelStr;
- cd->color = (valueP?*valueP:0);
- bb = wButtonCreate( parent, x, y, helpStr, (const char*)bm, option|BO_ICON, width, doColorButton, cd );
- cd->button = bb;
- if (labelStr)
- ((wControl_p)bb)->labelW = gtkAddLabel( (wControl_p)bb, labelStr );
- return bb;
-}
diff --git a/app/wlib/gtklib/gtkdraw-cairo.c b/app/wlib/gtklib/gtkdraw-cairo.c
index 9fc7eab..a19eb2b 100644
--- a/app/wlib/gtklib/gtkdraw-cairo.c
+++ b/app/wlib/gtklib/gtkdraw-cairo.c
@@ -1,5 +1,5 @@
-/*
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/wlib/gtklib/gtkdraw-cairo.c,v 1.11 2009-10-03 17:34:37 dspagnol Exp $
+/** \file gtkdraw-cairo.c
+ * Basic drawing functions
*/
/* XTrkCad - Model Railroad CAD
@@ -29,9 +29,13 @@
#include <string.h>
#include <math.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
#include "gtkint.h"
#include "gdk/gdkkeysyms.h"
+#define gtkAddHelpString( a, b ) wlibAddHelpString( a, b )
#define CENTERMARK_LENGTH (6)
@@ -116,7 +120,7 @@ static GdkGC * selectGC(
{
if(bd->lastColor != color || !bd->lastColorInverted)
{
- gdk_gc_set_foreground( bd->gc, gtkGetColor(color,FALSE) );
+ gdk_gc_set_foreground( bd->gc, wlibGetColor(color,FALSE) );
bd->lastColor = color;
bd->lastColorInverted = TRUE;
}
@@ -127,7 +131,7 @@ static GdkGC * selectGC(
{
if(bd->lastColor != color || bd->lastColorInverted)
{
- gdk_gc_set_foreground( bd->gc, gtkGetColor(color,TRUE) );
+ gdk_gc_set_foreground( bd->gc, wlibGetColor(color,TRUE) );
bd->lastColor = color;
bd->lastColorInverted = FALSE;
}
@@ -182,7 +186,7 @@ static cairo_t* gtkDrawCreateCairoContext(
}
else
{
- GdkColor* const gcolor = gtkGetColor(color, TRUE);
+ GdkColor* const gcolor = wlibGetColor(color, TRUE);
cairo_set_source_rgb(cairo, gcolor->red / 65535.0, gcolor->green / 65535.0, gcolor->blue / 65535.0);
cairo_set_operator(cairo, CAIRO_OPERATOR_OVER);
@@ -195,7 +199,7 @@ static cairo_t* gtkDrawDestroyCairoContext(cairo_t *cairo) {
cairo_destroy(cairo);
}
-EXPORT void wDrawDelayUpdate(
+ void wDrawDelayUpdate(
wDraw_p bd,
wBool_t delay )
{
@@ -212,7 +216,7 @@ EXPORT void wDrawDelayUpdate(
}
-EXPORT void wDrawLine(
+ void wDrawLine(
wDraw_p bd,
wPos_t x0, wPos_t y0,
wPos_t x1, wPos_t y1,
@@ -275,7 +279,7 @@ EXPORT void wDrawLine(
*/
-EXPORT void wDrawArc(
+ void wDrawArc(
wDraw_p bd,
wPos_t x0, wPos_t y0,
wPos_t r,
@@ -344,7 +348,7 @@ EXPORT void wDrawArc(
}
-EXPORT void wDrawPoint(
+ void wDrawPoint(
wDraw_p bd,
wPos_t x0, wPos_t y0,
wDrawColor color,
@@ -380,7 +384,7 @@ EXPORT void wDrawPoint(
*
******************************************************************************/
-EXPORT void wDrawString(
+ void wDrawString(
wDraw_p bd,
wPos_t x, wPos_t y,
wAngle_t a,
@@ -413,19 +417,19 @@ EXPORT void wDrawString(
cairo_translate( cairo, x, y );
cairo_rotate( cairo, angle );
- layout = gtkFontCreatePangoLayout(bd->widget, cairo, fp, fs, s,
+ layout = wlibFontCreatePangoLayout(bd->widget, cairo, fp, fs, s,
(int *) &w, (int *) &h,
(int *) &ascent, (int *) &descent);
/* cairo does not support the old method of text removal by overwrite; force always write here and
refresh on cancel event */
- GdkColor* const gcolor = gtkGetColor(color, TRUE);
+ GdkColor* const gcolor = wlibGetColor(color, TRUE);
cairo_set_source_rgb(cairo, gcolor->red / 65535.0, gcolor->green / 65535.0, gcolor->blue / 65535.0);
cairo_move_to( cairo, 0, -ascent );
pango_cairo_show_layout(cairo, layout);
- gtkFontDestroyPangoLayout(layout);
+ wlibFontDestroyPangoLayout(layout);
cairo_restore( cairo );
gtkDrawDestroyCairoContext(cairo);
@@ -442,7 +446,7 @@ EXPORT void wDrawString(
gtk_widget_draw(bd->widget, &update_rect);
}
-EXPORT void wDrawGetTextSize(
+ void wDrawGetTextSize(
wPos_t *w,
wPos_t *h,
wPos_t *d,
@@ -459,8 +463,8 @@ EXPORT void wDrawGetTextSize(
*w = 0;
*h = 0;
- gtkFontDestroyPangoLayout(
- gtkFontCreatePangoLayout(bd->widget, NULL, fp, fs, s,
+ wlibFontDestroyPangoLayout(
+ wlibFontCreatePangoLayout(bd->widget, NULL, fp, fs, s,
&textWidth, (int *) &textHeight,
(int *) &ascent, (int *) &descent));
@@ -479,7 +483,7 @@ EXPORT void wDrawGetTextSize(
*
*******************************************************************************/
-EXPORT void wDrawFilledRectangle(
+ void wDrawFilledRectangle(
wDraw_p bd,
wPos_t x,
wPos_t y,
@@ -518,7 +522,7 @@ EXPORT void wDrawFilledRectangle(
gtk_widget_draw( bd->widget, &update_rect );
}
-EXPORT void wDrawFilledPolygon(
+ void wDrawFilledPolygon(
wDraw_p bd,
wPos_t p[][2],
int cnt,
@@ -584,7 +588,7 @@ EXPORT void wDrawFilledPolygon(
gtk_widget_draw( bd->widget, &update_rect );
}
-EXPORT void wDrawFilledCircle(
+ void wDrawFilledCircle(
wDraw_p bd,
wPos_t x0,
wPos_t y0,
@@ -623,7 +627,7 @@ EXPORT void wDrawFilledCircle(
}
-EXPORT void wDrawClear(
+ void wDrawClear(
wDraw_p bd )
{
GdkGC * gc;
@@ -648,7 +652,7 @@ EXPORT void wDrawClear(
gtk_widget_draw( bd->widget, &update_rect );
}
-EXPORT void * wDrawGetContext(
+ void * wDrawGetContext(
wDraw_p bd )
{
return bd->context;
@@ -661,7 +665,7 @@ EXPORT void * wDrawGetContext(
*******************************************************************************/
-EXPORT wDrawBitMap_p wDrawBitMapCreate(
+ wDrawBitMap_p wDrawBitMapCreate(
wDraw_p bd,
int w,
int h,
@@ -682,7 +686,7 @@ EXPORT wDrawBitMap_p wDrawBitMapCreate(
}
-EXPORT void wDrawBitMap(
+ void wDrawBitMap(
wDraw_p bd,
wDrawBitMap_p bm,
wPos_t x, wPos_t y,
@@ -713,7 +717,7 @@ EXPORT void wDrawBitMap(
} else if ( (opts&wDrawOptNoClip) != 0 ) {
xx += bd->realX;
yy += bd->realY;
- b = gtkGetControlFromPos( bd->parent, xx, yy );
+ b = wlibGetControlFromPos( bd->parent, xx, yy );
if ( b ) {
if ( b->type == B_DRAW )
gdk_window = ((wDraw_p)b)->pixmap;
@@ -762,7 +766,7 @@ EXPORT void wDrawBitMap(
-EXPORT void wDrawSaveImage(
+ void wDrawSaveImage(
wDraw_p bd )
{
if ( bd->pixmapBackup ) {
@@ -781,7 +785,7 @@ EXPORT void wDrawSaveImage(
}
-EXPORT void wDrawRestoreImage(
+ void wDrawRestoreImage(
wDraw_p bd )
{
GdkRectangle update_rect;
@@ -806,7 +810,7 @@ EXPORT void wDrawRestoreImage(
}
-EXPORT void wDrawSetSize(
+ void wDrawSetSize(
wDraw_p bd,
wPos_t w,
wPos_t h )
@@ -838,13 +842,13 @@ EXPORT void wDrawSetSize(
}
-EXPORT void wDrawGetSize(
+ void wDrawGetSize(
wDraw_p bd,
wPos_t *w,
wPos_t *h )
{
if (bd->widget)
- gtkControlGetSize( (wControl_p)bd );
+ wlibControlGetSize( (wControl_p)bd );
*w = bd->w-2;
*h = bd->h-2;
}
@@ -856,7 +860,7 @@ EXPORT void wDrawGetSize(
* \return the resolution in dpi
*/
-EXPORT double wDrawGetDPI(
+ double wDrawGetDPI(
wDraw_p d )
{
//if (d == &psPrint_d)
@@ -866,7 +870,7 @@ EXPORT double wDrawGetDPI(
}
-EXPORT double wDrawGetMaxRadius(
+ double wDrawGetMaxRadius(
wDraw_p d )
{
if (d == &psPrint_d)
@@ -876,7 +880,7 @@ EXPORT double wDrawGetMaxRadius(
}
-EXPORT void wDrawClip(
+ void wDrawClip(
wDraw_p d,
wPos_t x,
wPos_t y,
@@ -956,7 +960,7 @@ static gint draw_leave_event(
GtkWidget *widget,
GdkEvent * event )
{
- gtkHelpHideBalloon();
+ wlibHelpHideBalloon();
return FALSE;
}
@@ -1041,38 +1045,38 @@ static gint draw_char_event(
guint key = event->keyval;
wAccelKey_e extKey = wAccelKey_None;
switch (key) {
- case GDK_Escape: key = 0x1B; break;
- case GDK_Return: key = 0x0D; break;
- case GDK_Linefeed: key = 0x0A; break;
- case GDK_Tab: key = 0x09; break;
- case GDK_BackSpace: key = 0x08; break;
- case GDK_Delete: extKey = wAccelKey_Del; break;
- case GDK_Insert: extKey = wAccelKey_Ins; break;
- case GDK_Home: extKey = wAccelKey_Home; break;
- case GDK_End: extKey = wAccelKey_End; break;
- case GDK_Page_Up: extKey = wAccelKey_Pgup; break;
- case GDK_Page_Down: extKey = wAccelKey_Pgdn; break;
- case GDK_Up: extKey = wAccelKey_Up; break;
- case GDK_Down: extKey = wAccelKey_Down; break;
- case GDK_Right: extKey = wAccelKey_Right; break;
- case GDK_Left: extKey = wAccelKey_Left; break;
- case GDK_F1: extKey = wAccelKey_F1; break;
- case GDK_F2: extKey = wAccelKey_F2; break;
- case GDK_F3: extKey = wAccelKey_F3; break;
- case GDK_F4: extKey = wAccelKey_F4; break;
- case GDK_F5: extKey = wAccelKey_F5; break;
- case GDK_F6: extKey = wAccelKey_F6; break;
- case GDK_F7: extKey = wAccelKey_F7; break;
- case GDK_F8: extKey = wAccelKey_F8; break;
- case GDK_F9: extKey = wAccelKey_F9; break;
- case GDK_F10: extKey = wAccelKey_F10; break;
- case GDK_F11: extKey = wAccelKey_F11; break;
- case GDK_F12: extKey = wAccelKey_F12; break;
+ case GDK_KEY_Escape: key = 0x1B; break;
+ case GDK_KEY_Return: key = 0x0D; break;
+ case GDK_KEY_Linefeed: key = 0x0A; break;
+ case GDK_KEY_Tab: key = 0x09; break;
+ case GDK_KEY_BackSpace: key = 0x08; break;
+ case GDK_KEY_Delete: extKey = wAccelKey_Del; break;
+ case GDK_KEY_Insert: extKey = wAccelKey_Ins; break;
+ case GDK_KEY_Home: extKey = wAccelKey_Home; break;
+ case GDK_KEY_End: extKey = wAccelKey_End; break;
+ case GDK_KEY_Page_Up: extKey = wAccelKey_Pgup; break;
+ case GDK_KEY_Page_Down: extKey = wAccelKey_Pgdn; break;
+ case GDK_KEY_Up: extKey = wAccelKey_Up; break;
+ case GDK_KEY_Down: extKey = wAccelKey_Down; break;
+ case GDK_KEY_Right: extKey = wAccelKey_Right; break;
+ case GDK_KEY_Left: extKey = wAccelKey_Left; break;
+ case GDK_KEY_F1: extKey = wAccelKey_F1; break;
+ case GDK_KEY_F2: extKey = wAccelKey_F2; break;
+ case GDK_KEY_F3: extKey = wAccelKey_F3; break;
+ case GDK_KEY_F4: extKey = wAccelKey_F4; break;
+ case GDK_KEY_F5: extKey = wAccelKey_F5; break;
+ case GDK_KEY_F6: extKey = wAccelKey_F6; break;
+ case GDK_KEY_F7: extKey = wAccelKey_F7; break;
+ case GDK_KEY_F8: extKey = wAccelKey_F8; break;
+ case GDK_KEY_F9: extKey = wAccelKey_F9; break;
+ case GDK_KEY_F10: extKey = wAccelKey_F10; break;
+ case GDK_KEY_F11: extKey = wAccelKey_F11; break;
+ case GDK_KEY_F12: extKey = wAccelKey_F12; break;
default: ;
}
if (extKey != wAccelKey_None) {
- if ( gtkFindAccelKey( event ) == NULL ) {
+ if ( wlibFindAccelKey( event ) == NULL ) {
bd->action( bd, bd->context, wActionExtKey + ((int)extKey<<8), bd->lastX, bd->lastY );
}
return TRUE;
@@ -1097,7 +1101,7 @@ int XW = 0;
int XH = 0;
int xw, xh, cw, ch;
-EXPORT wDraw_p wDrawCreate(
+ wDraw_p wDrawCreate(
wWin_p parent,
wPos_t x,
wPos_t y,
@@ -1111,12 +1115,12 @@ EXPORT wDraw_p wDrawCreate(
{
wDraw_p bd;
- bd = (wDraw_p)gtkAlloc( parent, B_DRAW, x, y, NULL, sizeof *bd, NULL );
+ bd = (wDraw_p)wlibAlloc( parent, B_DRAW, x, y, NULL, sizeof *bd, NULL );
bd->option = option;
bd->context = context;
bd->redraw = redraw;
bd->action = action;
- gtkComputePos( (wControl_p)bd );
+ wlibComputePos( (wControl_p)bd );
bd->widget = gtk_drawing_area_new();
gtk_drawing_area_size( GTK_DRAWING_AREA(bd->widget), width, height );
@@ -1153,7 +1157,7 @@ EXPORT wDraw_p wDrawCreate(
bd->maxH = bd->h = height;
gtk_fixed_put( GTK_FIXED(parent->widget), bd->widget, bd->realX, bd->realY );
- gtkControlGetSize( (wControl_p)bd );
+ wlibControlGetSize( (wControl_p)bd );
gtk_widget_realize( bd->widget );
bd->pixmap = gdk_pixmap_new( bd->widget->window, width, height, -1 );
bd->gc = gdk_gc_new( parent->gtkwin->window );
@@ -1169,7 +1173,7 @@ EXPORT wDraw_p wDrawCreate(
bd->labelW = gtkAddLabel( (wControl_p)bd, labelStr );
#endif
gtk_widget_show( bd->widget );
- gtkAddButton( (wControl_p)bd );
+ wlibAddButton( (wControl_p)bd );
gtkAddHelpString( bd->widget, helpStr );
return bd;
@@ -1185,7 +1189,7 @@ wDraw_p wBitMapCreate( wPos_t w, wPos_t h, int arg )
{
wDraw_p bd;
- bd = (wDraw_p)gtkAlloc( gtkMainW, B_DRAW, 0, 0, NULL, sizeof *bd, NULL );
+ bd = (wDraw_p)wlibAlloc( gtkMainW, B_DRAW, 0, 0, NULL, sizeof *bd, NULL );
bd->lastColor = -1;
bd->dpi = 75;
diff --git a/app/wlib/gtklib/gtkfont.c b/app/wlib/gtklib/gtkfont.c
deleted file mode 100644
index 89937d7..0000000
--- a/app/wlib/gtklib/gtkfont.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/** \file gtkfont.c
- * Font selection and loading.
- */
-
-/* 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 <stdlib.h>
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-#include <unistd.h>
-#include <string.h>
-#include <math.h>
-#include <stdlib.h>
-
-#include "wlib.h"
-#include "gtkint.h"
-#include "i18n.h"
-
-#ifndef TRUE
-#define TRUE (1)
-#define FALSE (0)
-#endif
-
-/*
- * Macro for debug purposes. Possible debug macro values:
- *
- * 0 - no messages to console (use this value when building in release mode)
- * 1 - send errors
- * 2 - send details
- * 3 - send more details
- */
-#define WLIB_FONT_DEBUG 0
-
-static gchar sampleText[] = "AbCdE0129!@$&()[]{}";
-
-static GtkWidget *fontSelectionDialog;
-
-
-/*****************************************************************************
- * FONT HANDLERS
- */
-
-#define FW_MEDIUM (0)
-#define FW_BOLD (1)
-#define FS_REGULAR (0)
-#define FS_ITALIC (1)
-
-/* absoluteFontSize was introduced to keep the font size information synchron
- * between the Dt.size of ctext.c and it's drop list on the status bar and
- * the font size coming from the gtk font dialog which is located in this file */
-int absoluteFontSize = 18;
-
-struct wFont_t {
- PangoFontDescription *fontDescription;
- };
-
-static wFont_p standardFonts[F_HELV-F_TIMES+1][2][2];
-static wFont_p curFont = NULL;
-
-
-static void fontSelectionDialogCallback(GtkFontSelectionDialog *fontSelectionDialog, gint response, gpointer data)
-{
- gchar *fontName;
-
- switch (response)
- {
- case GTK_RESPONSE_APPLY: /* once the apply button is hidden, this should not be used */
- case GTK_RESPONSE_OK:
- fontName = gtk_font_selection_dialog_get_font_name(fontSelectionDialog);
- wPrefSetString( "font", "name", fontName );
- pango_font_description_free(curFont->fontDescription);
- curFont->fontDescription = pango_font_description_from_string(fontName);
- absoluteFontSize = (pango_font_description_get_size(curFont->fontDescription))/PANGO_SCALE;
-#if WLIB_FONT_DEBUG >= 2
- fprintf(stderr, "new font selection:\n");
- fprintf(stderr, " font name \"%s\"\n", fontName);
- fprintf(stderr, " font size is %d\n",pango_font_description_get_size(curFont->fontDescription)/PANGO_SCALE);
- fprintf(stderr, " font size is absolute %d\n", pango_font_description_get_size_is_absolute(curFont->fontDescription));
-#endif
- g_free(fontName);
- break;
- default:
- gtk_widget_hide(GTK_WIDGET(fontSelectionDialog));
- }
- if (response == GTK_RESPONSE_OK)
- gtk_widget_hide(GTK_WIDGET(fontSelectionDialog));
-}
-
-static wBool_t fontInitted = FALSE;
-
-static wBool_t fontInit()
-{
- const char *fontNames[] = {
- "times 18",
- "times italic 18",
- "times bold 18",
- "times bold italic 18",
- "helvetica 18",
- "helvetica oblique 18",
- "helvetica bold 18",
- "helvetica bold oblique 18",
- };
-
- int s = 0;
- int i, j, k;
-
- for (i = F_TIMES; i <= F_HELV; ++i) {
- for (j = FW_MEDIUM; j <= FW_BOLD; ++j) {
- for (k = FS_REGULAR; k <= FS_ITALIC; ++k) {
- PangoFontDescription *fontDescription = pango_font_description_from_string(fontNames[s++]);
- wFont_p standardFont = (wFont_p) malloc(sizeof(struct wFont_t));
- standardFont->fontDescription = fontDescription;
- standardFonts[i-F_TIMES][j][k] = standardFont;
- }
- }
- }
-
- if (curFont == NULL) {
- curFont = (wFont_p) malloc(sizeof(struct wFont_t));
- if (curFont == NULL)
- return FALSE;
- const char *fontName = wPrefGetString("font", "name");
- curFont->fontDescription = pango_font_description_from_string(fontName ? fontName : "helvetica 18");
- absoluteFontSize = (int) PANGO_PIXELS(pango_font_description_get_size(curFont->fontDescription));
- }
-
- fontInitted = TRUE;
- return TRUE;
-}
-
-
-static double fontFactor = 1.0;
-
-#define FONTSIZE_TO_PANGOSIZE(fs) ((gint) ((fs) * (fontFactor) + .5))
-
-/**
- * Create a Pango layout with a specified font and font size
- *
- * \param widget IN
- * \param cairo IN cairo context
- * \param fp IN font
- * \param fs IN size
- * \param s IN ???
- * \param width_p OUT width of layout
- * \param height_p OUT height of layout
- * \param ascent_p OUT ascent of layout
- * \param descent_p OUT descent of layout
- * \return the created Pango layout
- */
-
-PangoLayout *gtkFontCreatePangoLayout(GtkWidget *widget,
- void *cairo,
- wFont_p fp,
- wFontSize_t fs,
- const char *s,
- int *width_p,
- int *height_p,
- int *ascent_p,
- int *descent_p)
-{
- if (!fontInitted)
- fontInit();
-
- PangoLayout *layout = NULL;
-
- gchar *utf8 = gtkConvertInput(s);
-
-/* RPH -- pango_cairo_create_layout() is missing in CentOS 4.8.
- CentOS 4.8 only has GTK 2.4.13 and Pango 1.6.0 and does not have
- libpangocairo at all.
- pango_cairo_create_layout() was introduced with Pango 1.10. */
-
-#if PANGO_VERSION_MAJOR >= 1 && PANGO_VERSION_MINOR >= 10
- if (cairo != NULL) {
- layout = pango_cairo_create_layout((cairo_t *) cairo);
- pango_layout_set_text(layout, utf8, -1);
- }
- else
-#endif
- layout = gtk_widget_create_pango_layout(widget, utf8);
-
- PangoFontDescription *fontDescription = (fp ? fp : curFont)->fontDescription;
-
- PangoContext *context;
- PangoFontMetrics *metrics;
-
- /* set attributes */
- pango_font_description_set_size(fontDescription,
- FONTSIZE_TO_PANGOSIZE(fs) * PANGO_SCALE);
- pango_layout_set_font_description(layout, fontDescription);
-
- /* get layout measures */
- pango_layout_get_pixel_size(layout, width_p, height_p);
- context = gtk_widget_get_pango_context(widget);
- metrics = pango_context_get_metrics(context, fontDescription,
- pango_context_get_language(context));
- *ascent_p = PANGO_PIXELS(pango_font_metrics_get_ascent(metrics));
- *descent_p = PANGO_PIXELS(pango_font_metrics_get_descent(metrics));
- pango_font_metrics_unref(metrics);
-
-#if WLIB_FONT_DEBUG >= 3
- fprintf(stderr, "font layout created:\n");
- fprintf(stderr, " widget: %p\n", widget);
- //fprintf(stderr, " font description:%p\n", fp);
- fprintf(stderr, " font size: %f\n", fs);
- fprintf(stderr, " layout text: \"%s\" (utf8)\n", utf8);
- fprintf(stderr, " layout width: %d\n", *width_p);
- fprintf(stderr, " layout height: %d\n", *height_p);
- fprintf(stderr, " layout ascent: %d (pixels)\n", *ascent_p);
- fprintf(stderr, " layout descent: %d (pixels)\n", *descent_p);
-#endif
-
- return layout;
-}
-
-void gtkFontDestroyPangoLayout(PangoLayout *layout)
-{
- g_object_unref(G_OBJECT(layout));
-}
-
-void wInitializeFonts()
-{
- if (!fontInitted)
- fontInit();
-}
-
-void wSelectFont(
- const char * title )
-{
- if (!fontInitted)
- fontInit();
-
- if (fontSelectionDialog == NULL) {
- fontSelectionDialog = gtk_font_selection_dialog_new(_("Font Select"));
- gtk_window_set_position(GTK_WINDOW(fontSelectionDialog), GTK_WIN_POS_MOUSE);
- gtk_window_set_modal(GTK_WINDOW(fontSelectionDialog), TRUE);
- gtk_font_selection_dialog_set_preview_text(GTK_FONT_SELECTION_DIALOG(fontSelectionDialog), sampleText);
- g_signal_connect(G_OBJECT(fontSelectionDialog), "response", G_CALLBACK(fontSelectionDialogCallback), NULL);
- gtk_signal_connect(GTK_OBJECT(fontSelectionDialog), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &fontSelectionDialog);
- }
- gtk_window_set_title(GTK_WINDOW(fontSelectionDialog), title);
-
- if (curFont != NULL) {
- /* the curFont description contains the latest font info
- * which is depended on the current scale
- * overwrite it with the absoluteFontSize */
- pango_font_description_set_size(curFont->fontDescription,FONTSIZE_TO_PANGOSIZE(absoluteFontSize) * PANGO_SCALE);
- gchar *fontName = pango_font_description_to_string(curFont->fontDescription);
- gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(fontSelectionDialog), fontName);
- g_free(fontName);
- }
-
- gtk_widget_show(fontSelectionDialog);
-}
-
-static wFont_p gtkSelectedFont( void )
-{
- if (!fontInitted)
- fontInit();
-
- return curFont;
-}
-
-wFontSize_t wSelectedFontSize( void )
-{
- if (!fontInitted)
- fontInit();
-
-#if WLIB_FONT_DEBUG >= 3
- fprintf(stderr, "the font size of current font description is: %d\n",pango_font_description_get_size(curFont->fontDescription)/PANGO_SCALE);
- fprintf(stderr, "the font size of absoluteFontSize is: %d\n",absoluteFontSize);
-#endif
-
- //return (wFontSize_t) PANGO_PIXELS(pango_font_description_get_size(curFont->fontDescription));
- return absoluteFontSize;
-}
-
-void wSetSelectedFontSize(int size){
- absoluteFontSize = (wFontSize_t)size;
-}
-
-/**
- * get the Pango font description as a string from a font definition.
- * If the font definition is NULL, a default font is return. This is
- * the current font if one is set. If not the first font from the font
- * list is returned.
- *
- * \param fp IN the font definition
- * \return the font description
- */
-
-const char *gtkFontTranslate( wFont_p fp )
-{
- static gchar *fontName = NULL;
-
- if (fontName != NULL)
- g_free(fontName);
-
- if (!fontInitted)
- fontInit();
-
- if (fp == NULL)
- fp = gtkSelectedFont();
-
- if (fp == NULL)
- fp = standardFonts[0][FW_MEDIUM][FS_REGULAR];
-
- fontName = pango_font_description_to_string(fp->fontDescription);
-
-#if WLIB_FONT_DEBUG >= 2
- fprintf(stderr, "font translation: ");
- fprintf(stderr, " \"%s\"\n", fontName);
-#endif
-
- return (const char *) fontName;
-}
-
-wFont_p wStandardFont( int face, wBool_t bold, wBool_t italic )
-{
- if (!fontInitted)
- fontInit();
-
- return standardFonts[face-F_TIMES][bold][italic];
-}
diff --git a/app/wlib/gtklib/gtkhelp.c b/app/wlib/gtklib/gtkhelp.c
deleted file mode 100644
index b02f555..0000000
--- a/app/wlib/gtklib/gtkhelp.c
+++ /dev/null
@@ -1,733 +0,0 @@
-/** \file gtkhelp.c
- * Balloon help ( tooltips) and main help functions.
- *
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/wlib/gtklib/gtkhelp.c,v 1.12 2009-10-02 04:30:32 dspagnol Exp $
- */
-
-/* XTrkCad - Model Railroad CAD
- * Copyright (C) 2005 Dave Bullis and (C) 2007 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 <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>
-
-#include <gtk/gtk.h>
-#include <gdk/gdk.h>
-
-#include <webkit/webkit.h>
-
-#include "gtkint.h"
-#include "i18n.h"
-
-void load_into_view (char *file, int requested_view); // Prototype to please clang.
-
-/* globals and defines related to the HTML help window */
-
-#define HTMLERRORTEXT "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=US-ASCII\">" \
- "<title>Help Error</title><body><h1>Error - help information can not be found.</h1><p>" \
- "The help information you requested cannot be found on this system.<br><pre>%s: %s</pre><p>" \
- "Usually this is an installation problem, Make sure that XTrackCAD and the included " \
- "HTML files are installed properly and can be found via the XTRKCADLIB environment " \
- "variable. Also make sure that the user has sufficient access rights to read these" \
- "files.</p></body></html>"
-
-
-#define SLIDERPOSDEFAULT 180 /**< default value for slider position */
-
-#define HTMLHELPSECTION "gtklib html help" /**< section name for html help window preferences */
-#define SLIDERPREFNAME "sliderpos" /**< name for the slider position preference */
-#define WINDOWPOSPREFNAME "position" /**< name for the window position preference */
-#define WINDOWSIZEPREFNAME "size" /**< name for the window size preference */
-
-#define BACKBUTTON "back"
-#define FORWARDBUTTON "forward"
-#define HOMEBUTTON "home"
-#define CONTENTBUTTON "contents"
-#define TOCDOC "tocDoc"
-#define CONTENTSDOC "contentsDoc"
-#define TOCVIEW "viewLeft"
-#define CONTENTSVIEW "viewRight"
-#define PANED "hpane"
-
-enum pane_views { MAIN_VIEW, CONTENTS_VIEW };
-
-#define MAXHISTORYSIZE 20
-
-/** \struct htmlHistory
- * for storing information about the browse history
- */
-struct htmlHistory {
- int curShownPage; /**< index of page that is shown currently */
- int newestPage; /**< index of newest page loaded */
- int oldestPage; /**< index of earliest page loaded */
- int bInUse; /**< does buffer have at least one entry */
- char *url[ MAXHISTORYSIZE ]; /**< array of pages in history */
-};
-
-static struct htmlHistory sHtmlHistory;
-
-#define INCBUFFERINDEX( x ) (((x) + 1 ) % MAXHISTORYSIZE )
-#define DECBUFFERINDEX( x ) ((x) == 0 ? MAXHISTORYSIZE - 1 : (x)-1)
-
-static char *directory; /**< base directory for HTML files */
-
-static GtkWidget *wHelpWindow; /**< handle for the help window */
-static GtkWidget *main_view; /** handle for the help main data pane */
-static GtkWidget *contents_view; /** handle for the help contents pane */
-
-#define GLADE_HOOKUP_OBJECT(component,widget,name) \
- g_object_set_data_full (G_OBJECT (component), name, \
- gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
-
-#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
- g_object_set_data (G_OBJECT (component), name, widget)
-
-static GtkWidget*
-lookup_widget(GtkWidget *widget, const gchar *widget_name)
-{
- GtkWidget *parent, *found_widget;
-
- for (;;)
- {
- if (GTK_IS_MENU (widget))
- parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
- else
- parent = widget->parent;
- if (!parent)
- parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey");
- if (parent == NULL)
- break;
- widget = parent;
- }
-
- found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget),
- widget_name);
- if (!found_widget)
- g_warning ("Widget not found: %s", widget_name);
- return found_widget;
-}
-
-
-
-/*
- ******************************************************************************
- *
- * Help
- *
- ******************************************************************************
- */
-
-wBool_t listHelpStrings = FALSE;
-wBool_t listMissingHelpStrings = FALSE;
-static char HelpDataKey[] = "HelpDataKey";
-
-static GtkWidget * balloonF;
-static GtkWidget * balloonPI;
-static wBalloonHelp_t * balloonHelpStrings;
-static int enableBalloonHelp = 1;
-static const char * balloonMsg;
-static wControl_p balloonB;
-static wPos_t balloonDx, balloonDy;
-static wBool_t balloonVisible = FALSE;
-static wControl_p balloonHelpB;
-static GtkTooltips * tooltips;
-
-
-void wSetBalloonHelp( wBalloonHelp_t * bh )
-{
- balloonHelpStrings = bh;
- if (!tooltips)
- tooltips = gtk_tooltips_new();
-}
-
-void wEnableBalloonHelp( int enable )
-{
- enableBalloonHelp = enable;
- if (tooltips) {
- if (enable)
- gtk_tooltips_enable( tooltips );
- else
- gtk_tooltips_disable( tooltips );
- }
-}
-
-
-void wControlSetBalloon( wControl_p b, wPos_t dx, wPos_t dy, const char * msg )
-{
- PangoLayout * layout;
- wPos_t x, y;
- wPos_t w, h;
- wPos_t xx, yy;
- const char * msgConverted;
- if (balloonVisible && balloonB == b &&
- balloonDx == dx && balloonDy == dy && balloonMsg == msg )
- return;
-
- if ( msg == NULL ) {
- if ( balloonF != NULL ) {
- gtk_widget_hide( balloonF );
- balloonVisible = FALSE;
- }
- balloonMsg = "";
- return;
- }
- msgConverted = gtkConvertInput(msg);
- if ( balloonF == NULL ) {
- balloonF = gtk_window_new( GTK_WINDOW_POPUP );
- gtk_window_set_policy( GTK_WINDOW (balloonF), FALSE, FALSE, TRUE );
- gtk_widget_realize( balloonF );
- balloonPI = gtk_label_new(msgConverted);
- gtk_container_add( GTK_CONTAINER(balloonF), balloonPI );
- gtk_container_border_width( GTK_CONTAINER(balloonF), 1 );
- gtk_widget_show( balloonPI );
- } else {
- gtk_label_set( GTK_LABEL(balloonPI), msgConverted );
- }
- balloonDx = dx;
- balloonDy = dy;
- balloonB = b;
- balloonMsg = msg;
- gtk_widget_hide( balloonF );
- layout = gtk_widget_create_pango_layout( balloonPI, msgConverted );
- pango_layout_get_pixel_size( layout, &w, &h );
- g_object_unref(G_OBJECT(layout));
- h = 16;
- gdk_window_get_position( GTK_WIDGET(b->parent->gtkwin)->window, &x, &y );
- gdk_window_get_origin( GTK_WIDGET(b->parent->gtkwin)->window, &x, &y );
- x += b->realX + dx;
- y += b->realY + b->h - dy;
- xx = gdk_screen_width();
- yy = gdk_screen_height();
- if ( x < 0 ) {
- x = 0;
- } else if ( x+w > xx ) {
- x = xx - w;
- }
- if ( y < 0 ) {
- y = 0;
- } else if ( y+h > yy ) {
- y = yy - h ;
- }
- gtk_widget_set_usize( balloonPI, w, h );
- gtk_widget_set_usize( balloonF, w+2, h+2 );
- gtk_widget_show( balloonF );
- gtk_widget_set_uposition( balloonF, x, y );
- /*gtk_widget_popup( balloonF, x, y );*/
- gdk_draw_rectangle( balloonF->window, balloonF->style->fg_gc[GTK_STATE_NORMAL], FALSE, 0, 0, w+1, h+1 );
- gtk_widget_queue_resize( GTK_WIDGET(balloonF) );
- /*gtk_widget_set_uposition( balloonF, x, y );*/
- balloonVisible = TRUE;
-}
-
-
-void wControlSetBalloonText(
- wControl_p b,
- const char * label )
-{
- const char * helpStr;
- if ( b->widget == NULL) abort();
- helpStr = (char*)gtk_object_get_data( GTK_OBJECT(b->widget), HelpDataKey );
- if ( helpStr == NULL ) helpStr = "NoHelp";
- if (tooltips)
- gtk_tooltips_set_tip( tooltips, b->widget, label, helpStr );
-}
-
-
-EXPORT void gtkHelpHideBalloon( void )
-{
- if (balloonF != NULL && balloonVisible) {
- gtk_widget_hide( balloonF );
- balloonVisible = FALSE;
- }
-}
-
-#ifdef XV_help
-static Notify_value showBalloonHelp( Notify_client client, int which )
-{
- wControlSetBalloon( balloonHelpB, 0, 0, balloonHelpString );
- return NOTIFY_DONE;
-}
-#endif
-
-static wWin_p balloonHelp_w;
-static wPos_t balloonHelp_x;
-static wPos_t balloonHelp_y;
-static void prepareBalloonHelp( wWin_p w, wPos_t x, wPos_t y )
-{
-#ifdef XV
- wControl_p b;
- char * hs;
- int appNameLen = strlen( wAppName ) + 1;
- if (w == NULL)
- return;
-#ifdef LATER
- if (!enableBalloonHelp)
- return;
-#endif
- if (!balloonHelpStrings)
- return;
-
- balloonHelp_w = w;
- balloonHelp_x = x;
- balloonHelp_y = y;
-
- for ( b=w->first; b; b=b->next ) {
- switch ( b->type ) {
- case B_BUTTON:
- case B_CANCEL:
- case B_TEXT:
- case B_INTEGER:
- case B_LIST:
- case B_DROPLIST:
- case B_COMBOLIST:
- case B_RADIO:
- case B_TOGGLE:
- case B_DRAW:
- case B_MULTITEXT:
- if (x >= b->realX && x < b->realX+b->w &&
- y >= b->realY && y < b->realY+b->h ) {
- hs = (char*)gtk_get( b->panel_item, XV_HELP_DATA );
- if ( hs ) {
- hs += appNameLen;
- for ( currBalloonHelp = balloonHelpStrings; currBalloonHelp->name && strcmp(currBalloonHelp->name,hs) != 0; currBalloonHelp++ );
- if (currBalloonHelp->name && balloonHelpB != b && currBalloonHelp->value ) {
- balloonHelpB = b;
- balloonHelpString = currBalloonHelp->value;
- if (enableBalloonHelp) {
- wControlSetBalloon( balloonHelpB, 0, 0, balloonHelpString );
- /*setTimer( balloonHelpTimeOut, showBalloonHelp );*/
- } else {
- /*resetBalloonHelp();*/
- }
- }
- return;
- }
- }
- default:
- ;
- }
- }
- cancelTimer( showBalloonHelp );
- resetBalloonHelp();
-#endif
-}
-
-
-void wBalloonHelpUpdate( void )
-{
- balloonHelpB = NULL;
- balloonMsg = NULL;
- prepareBalloonHelp( balloonHelp_w, balloonHelp_x, balloonHelp_y );
-}
-
-
-void gtkAddHelpString(
- GtkWidget * widget,
- const char * helpStr )
-{
- int rc;
- char *string;
- wBalloonHelp_t * bhp;
- rc = 0;
- if (helpStr==NULL || *helpStr==0)
- return;
- if ( balloonHelpStrings == NULL )
- return;
- for ( bhp = balloonHelpStrings; bhp->name && strcmp(bhp->name,helpStr) != 0; bhp++ );
- if (listMissingHelpStrings && !bhp->name) {
- printf( "Missing Help String: %s\n", helpStr );
- return;
- }
- string = malloc( strlen(wAppName) + 5 + strlen(helpStr) + 1 );
- sprintf( string, "%sHelp/%s", wAppName, helpStr );
- if (tooltips)
- gtk_tooltips_set_tip( tooltips, widget, _(bhp->value), string );
- gtk_object_set_data( GTK_OBJECT( widget ), HelpDataKey, string );
- if (listHelpStrings)
- printf( "HELPSTR - %s\n", string );
-}
-
-
-EXPORT const char * wControlGetHelp(
- wControl_p b ) /* Control */
-/*
-Returns the help topic string associated with <b>.
-*/
-{
- const char * helpStr;
- helpStr = (char*)gtk_object_get_data( GTK_OBJECT(b->widget), HelpDataKey );
- return helpStr;
-}
-
-
-EXPORT void wControlSetHelp(
- wControl_p b, /* Control */
- const char * help ) /* topic string */
-/*
-Set the help topic string for <b> to <help>.
-*/
-{
- const char * helpStr;
- if (b->widget == 0) abort();
- helpStr = wControlGetHelp(b);
- if (tooltips)
- gtk_tooltips_set_tip( tooltips, b->widget, help, helpStr );
-}
-
-
-/**
- * create a new horizontal pane and place it into container.
- * The separator position is read from the resource configuration and set accordingly.
- * Also a callback is specified that will be executed when the slider has been moved.
- *
- * \PARAM container IN the container into which the pane will be stuffed.
- * \PARAM property IN the name of the property for the slider position
- *
- * \return the HPaned handle
- */
-
-GtkWidget *
-CreateHPaned( GtkBox *container, char *property )
-{
- GtkWidget *hpaned;
- long posSlider;
-
- /* the horizontal slider */
- hpaned = gtk_hpaned_new ();
- gtk_container_set_border_width (GTK_CONTAINER (hpaned), 6);
-
- wPrefGetInteger( HTMLHELPSECTION, SLIDERPREFNAME, &posSlider, SLIDERPOSDEFAULT );
- gtk_paned_set_position (GTK_PANED (hpaned), (int)posSlider);
-
- /* pack the horizontal slider into the main window */
- gtk_box_pack_start( container, hpaned, TRUE, TRUE, 0 );
- gtk_widget_show( hpaned );
-
- return( hpaned );
-}
-
-/**
- * Handler for the delete-event issued on the help window.We are saving window
- * information (eg. position) and are hiding the window instead of closing it.
- *
- * \PARAM win IN the window to be destroyed
- * \PARAM event IN unused
- * \PARAM ptr IN unused
- *
- * \RETURN FALSE
- */
-
-static gboolean
-DestroyHelpWindow( GtkWidget *win, GdkEvent *event, void *ptr )
-{
- int i;
- GtkWidget *widget;
- char tmp[ 20 ];
-
- gint x, y;
-
- /* get the slider position and save it */
- widget = lookup_widget( win, PANED );
- i = gtk_paned_get_position( GTK_PANED( widget ));
- wPrefSetInteger( HTMLHELPSECTION, SLIDERPREFNAME, i );
-
- /* get the window position */
- gtk_window_get_position( (GtkWindow *)win, &x, &y );
- sprintf( tmp, "%d %d", x, y );
- wPrefSetString( HTMLHELPSECTION, WINDOWPOSPREFNAME, tmp );
-
- /* get the window size */
- gtk_window_get_size( (GtkWindow *)win , &x, &y );
- sprintf( tmp, "%d %d", x, y );
- wPrefSetString( HTMLHELPSECTION, WINDOWSIZEPREFNAME, tmp );
-
- gtk_widget_hide( win );
- return TRUE;
-}
-
-void back_button_clicked(GtkWidget *widget, gpointer data) {
- webkit_web_view_go_back(WEBKIT_WEB_VIEW(data));
-}
-
-void forward_button_clicked(GtkWidget *widget, gpointer data) {
- webkit_web_view_go_forward(WEBKIT_WEB_VIEW(data));
-}
-
-void home_button_clicked(GtkWidget *widget, gpointer data) {
- load_into_view("index.html", MAIN_VIEW);
-}
-
-/* Toggles the contents pane */
-void contents_button_clicked(GtkWidget *widget, gpointer data) {
- if (gtk_paned_get_position(GTK_PANED(data)) < 50) {
- gtk_paned_set_position(GTK_PANED(data), 370);
- }
- else {
- gtk_paned_set_position(GTK_PANED(data), 0);
- }
-}
-
-gboolean contents_click_handler(
- WebKitWebView *web_view,
- WebKitWebFrame *frame,
- WebKitNetworkRequest *request,
- WebKitWebNavigationAction *navigation_action,
- WebKitWebPolicyDecision *policy_decision,
- gpointer data) {
-
- webkit_web_view_load_uri(WEBKIT_WEB_VIEW(data), webkit_network_request_get_uri(request));
-
- return TRUE;
-}
-
-/**
- * Initialize the buttons for the help window
- */
-void initialize_buttons (GtkWidget *main_vbox, GtkWidget *content_hpane) {
- GtkWidget *buttons_hbuttonbox;
- GtkWidget *back_button;
- GtkWidget *forward_button;
- GtkWidget *home_button;
- GtkWidget *contents_button;
-
- // define and attach signals to buttons
- back_button = gtk_button_new_with_label(_("Back"));
- g_signal_connect(back_button, "clicked", G_CALLBACK(back_button_clicked), G_OBJECT(main_view));
-
- forward_button = gtk_button_new_with_label(_("Forward"));
- g_signal_connect(forward_button, "clicked", G_CALLBACK(forward_button_clicked), G_OBJECT(main_view));
-
- home_button = gtk_button_new_with_label(_("Home"));
- g_signal_connect(home_button, "clicked", G_CALLBACK(home_button_clicked), G_OBJECT(main_view));
-
- contents_button = gtk_button_new_with_label(_("Contents"));
- g_signal_connect(contents_button, "clicked", G_CALLBACK(contents_button_clicked), G_OBJECT(content_hpane));
-
- // button layout
- buttons_hbuttonbox = gtk_hbutton_box_new();
- gtk_container_add(GTK_CONTAINER(buttons_hbuttonbox), back_button);
- gtk_container_add(GTK_CONTAINER(buttons_hbuttonbox), forward_button);
- gtk_container_add(GTK_CONTAINER(buttons_hbuttonbox), home_button);
- gtk_container_add(GTK_CONTAINER(buttons_hbuttonbox), contents_button);
- gtk_box_pack_start(GTK_BOX(main_vbox), buttons_hbuttonbox, FALSE, TRUE, 0);
- gtk_box_set_spacing(GTK_BOX(buttons_hbuttonbox), 6);
- gtk_button_box_set_layout(GTK_BUTTON_BOX(buttons_hbuttonbox), GTK_BUTTONBOX_START);
-
- /* Store pointers to all widgets, for use by lookup_widget(). */
- GLADE_HOOKUP_OBJECT (main_view, back_button, BACKBUTTON);
- GLADE_HOOKUP_OBJECT (main_view, forward_button, FORWARDBUTTON);
- GLADE_HOOKUP_OBJECT (main_view, home_button, HOMEBUTTON);
- GLADE_HOOKUP_OBJECT (main_view, contents_button, CONTENTBUTTON);
-}
-
-/**
- * Create the help windows including all contained widgets and the needed HTML documents.
- *
- * \RETURN handle of the created window.
- */
-
-GtkWidget*
-CreateHelpWindow (void)
-{
- GtkWidget *main_vbox;
- GtkWidget *main_view_scroller;
- GtkWidget *contents_view_scroller;
- GtkWidget *content_hpane;
-
- int width;
- int height;
- int x, y;
- int w = 0, h = 0;
- const char *pref;
- char title[100];
-
- wHelpWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
- width = gdk_screen_get_width( gtk_window_get_screen( (GtkWindow *)wHelpWindow ));
- height = gdk_screen_get_height( gtk_window_get_screen( (GtkWindow *)wHelpWindow ));
-
- pref = wPrefGetString( HTMLHELPSECTION, WINDOWSIZEPREFNAME );
- if( pref ) {
- sscanf( pref, "%d %d", &w, &h );
- if( w > width )
- w = width;
- if( h > height )
- h = height;
- }
- else {
- w = ( width * 2 )/ 5;
- h = height - 100;
- }
-
- pref = wPrefGetString( HTMLHELPSECTION, WINDOWPOSPREFNAME );
- if( pref ) {
- sscanf( pref, "%d %d", &x, &y );
- if( y > height - h )
- y = height - h;
-
- if( x > width - w )
- x = width - w;
- }
- else {
- x = ( width * 3 ) / 5 - 10;
- y = 70;
- }
-
- gtk_window_resize( (GtkWindow *)wHelpWindow, w, h );
- gtk_window_move( (GtkWindow *)wHelpWindow, x, y );
-
- gtk_window_set_title (GTK_WINDOW (wHelpWindow), "XTrkCad Help");
-
- g_signal_connect( G_OBJECT( wHelpWindow ), "delete-event", G_CALLBACK( DestroyHelpWindow ), NULL );
-
- main_view_scroller = gtk_scrolled_window_new(NULL, NULL);
- contents_view_scroller = gtk_scrolled_window_new(NULL, NULL);
- main_view = webkit_web_view_new();
- contents_view = webkit_web_view_new();
- // must be done here as it gets locked down later
- load_into_view ("contents.html", CONTENTS_VIEW);
- gtk_widget_set_size_request(GTK_WIDGET(wHelpWindow), x, y);
-
- main_vbox = gtk_vbox_new(FALSE, 5);
- gtk_container_add(GTK_CONTAINER(wHelpWindow), main_vbox);
-
- gtk_container_add(GTK_CONTAINER(main_view_scroller), main_view);
-
- gtk_container_add(GTK_CONTAINER(contents_view_scroller), contents_view);
-
- content_hpane = gtk_hpaned_new();
- initialize_buttons(main_vbox, content_hpane);
- gtk_container_add(GTK_CONTAINER(content_hpane), contents_view_scroller);
- gtk_container_add(GTK_CONTAINER(content_hpane), main_view_scroller);
- gtk_box_pack_start(GTK_BOX(main_vbox), content_hpane, TRUE, TRUE, 0);
-
- gtk_paned_set_position(GTK_PANED(content_hpane), 370);
-
- g_signal_connect(contents_view, "navigation-policy-decision-requested", G_CALLBACK(contents_click_handler), G_OBJECT(main_view));
-
- /* Store pointers to all widgets, for use by lookup_widget(). */
- GLADE_HOOKUP_OBJECT_NO_REF (wHelpWindow, wHelpWindow, "wHelpWindow");
- GLADE_HOOKUP_OBJECT (wHelpWindow, content_hpane, PANED );
- GLADE_HOOKUP_OBJECT (wHelpWindow, contents_view, TOCVIEW );
- GLADE_HOOKUP_OBJECT (wHelpWindow, main_view, CONTENTSVIEW );
-
- return wHelpWindow;
-}
-
-void load_into_view (char *file, int requested_view) {
- GtkWidget *view;
-
- switch (requested_view) {
- case MAIN_VIEW:
- view = main_view;
- break;
- case CONTENTS_VIEW:
- view = contents_view;
- break;
- default:
- printf("*** error, could not find view");
- break;
- }
-
- char fileToLoad[100] = "file://";
- strcat(fileToLoad,directory);
- strcat(fileToLoad,file);
-
- //debug printf("*** loading %s into pane %d.\n", fileToLoad, requested_view);
- webkit_web_view_load_uri(WEBKIT_WEB_VIEW(view), fileToLoad);
-}
-
-/**
- * Invoke the help system to display help for <topic>.
- *
- * \param topic IN topic string
- */
-
-EXPORT void wHelp( const char * topic )
-{
- char *htmlFile;
-
- if( !wHelpWindow )
- {
- directory = malloc( BUFSIZ );
- assert( directory != NULL );
-
- sprintf( directory, "%s/html/", wGetAppLibDir());
-
- wHelpWindow = CreateHelpWindow();
- /* load the default content */
- load_into_view ("index.html", MAIN_VIEW);
- }
-
- /* need space for the 'html' extension plus dot plus \0 */
- htmlFile = malloc( strlen( topic ) + 6 );
- assert( htmlFile != NULL );
-
- sprintf( htmlFile, "%s.html", topic );
-
- load_into_view (htmlFile, MAIN_VIEW);
- gtk_widget_show_all(wHelpWindow);
- gtk_window_present(GTK_WINDOW(wHelpWindow));
-}
-
-/**
- * Handle the commands issued from the Help drop-down. Currently, we only have a table
- * of contents, but search etc. might be added in the future.
- *
- * \PARAM data IN command value
- *
- */
-
-static void
-DoHelpMenu( void *data )
-{
- int func = (intptr_t)data;
-
- switch( func )
- {
- case 1:
- wHelp( "index" );
- break;
- default:
- break;
- }
-
- return;
-}
-
-/**
- * Add the entries for Help to the drop-down.
- *
- * \PARAM m IN handle of drop-down
- *
- */
-
-void wMenuAddHelp( wMenu_p m )
-{
- wMenuPushCreate( m, NULL, _("&Contents"), 0, DoHelpMenu, (void*)1 );
-}
diff --git a/app/wlib/gtklib/gtkint.h b/app/wlib/gtklib/gtkint.h
index c27c70b..da0d9ae 100644
--- a/app/wlib/gtklib/gtkint.h
+++ b/app/wlib/gtklib/gtkint.h
@@ -1,5 +1,5 @@
-/*
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/wlib/gtklib/gtkint.h,v 1.8 2009-12-12 17:16:08 m_fischer Exp $
+/** \file gtkint.h
+ * Internal definitions for the gtk-library
*/
/* XTrkCad - Model Railroad CAD
@@ -27,7 +27,6 @@
#include "gdk/gdk.h"
#include "gtk/gtk.h"
-#define EXPORT
#ifdef WINDOWS
#define strcasecmp _stricmp
@@ -35,6 +34,10 @@
#include "dynarr.h"
+#define BORDERSIZE (4)
+#define LABEL_OFFSET (3)
+#define MENUH (24)
+
extern wWin_p gtkMainW;
typedef enum {
@@ -84,6 +87,37 @@ struct wWin_t {
struct wControl_t {
WOBJ_COMMON
};
+
+typedef struct wListItem_t * wListItem_p;
+
+struct wList_t {
+ WOBJ_COMMON
+// GtkWidget *list;
+ int count;
+ int number;
+ int colCnt;
+ wPos_t *colWidths;
+ wBool_t *colRightJust;
+ GtkListStore *listStore;
+ GtkWidget *treeView;
+ int last;
+ wPos_t listX;
+ long * valueP;
+ wListCallBack_p action;
+ int recursion;
+ int editted;
+ int editable;
+ };
+
+
+struct wListItem_t {
+ wBool_t active;
+ void * itemData;
+ const char * label;
+ GtkLabel * labelG;
+ wBool_t selected;
+ wList_p listP;
+ };
#define gtkIcon_bitmap (1)
#define gtkIcon_pixmap (2)
@@ -95,83 +129,118 @@ struct wIcon_t {
const void * bits;
};
-extern char wAppName[];
extern char wConfigName[];
extern wDrawColor wDrawColorWhite;
extern wDrawColor wDrawColorBlack;
-/* gtkmisc.c */
-void * gtkAlloc( wWin_p, wType_e, wPos_t, wPos_t, const char *, int, void * );
-void gtkComputePos( wControl_p );
-void gtkAddButton( wControl_p );
-int gtkAddLabel( wControl_p, const char * );
-void gtkControlGetSize( wControl_p );
-struct accelData_t;
-struct accelData_t * gtkFindAccelKey( GdkEventKey * event );
-wBool_t gtkHandleAccelKey( GdkEventKey * );
-wBool_t catch_shift_ctrl_alt_keys( GtkWidget *, GdkEventKey *, void * );
-void gtkSetReadonly( wControl_p, wBool_t );
-wControl_p gtkGetControlFromPos( wWin_p, wPos_t, wPos_t );
-void gtkSetTrigger( wControl_p, setTriggerCallback_p );
-GdkPixmap * gtkMakeIcon( GtkWidget *, wIcon_p, GdkBitmap ** );
-char * gtkConvertInput( const char * );
-char * gtkConvertOutput( const char * );
-
-/* gtkwindow.c */
-void gtkDoModal( wWin_p, wBool_t );
-
-/* gtkhelp.c */
-void load_into_view( char *, int );
-void gtkAddHelpString( GtkWidget *, const char * );
-void gtkHelpHideBalloon( void );
-
-/* gtksimple.c */
-void gtkDrawBox( wWin_p, wBoxType_e, wPos_t, wPos_t, wPos_t, wPos_t );
-void gtkLineShow( wLine_p, wBool_t );
-
-/* gktlist.c */
-void gtkListShow( wList_p, wBool_t );
-void gtkListSetPos( wList_p );
-void gtkListActive( wList_p, wBool_t );
-void gtkDropListPos( wList_p );
-
-/* gtktext.c */
-void gtkTextFreeze( wText_p );
-void gtkTextThaw( wText_p );
-
-/* gtkfont.c */
-const char * gtkFontTranslate( wFont_p );
-PangoLayout *gtkFontCreatePangoLayout( GtkWidget *, void *cairo,
- wFont_p, wFontSize_t, const char *,
- int *, int *, int *, int * );
-
-/* gtkbutton.c */
-void gtkButtonDoAction( wButton_p );
-void gtkSetLabel( GtkWidget*, long, const char *, GtkLabel**, GtkWidget** );
-
-/* gtkcolor.c */
-void gtkGetColorMap( void );
-GdkColor * gtkGetColor( wDrawColor, wBool_t );
-int gtkGetColorChar( wDrawColor );
-void gtkPrintColorMap( FILE *, int, int );
-int gtkMapPixel( long );
-
-/* psprint.c */
-
-void WlibApplySettings( GtkPrintOperation *op );
-void WlibSaveSettings( GtkPrintOperation *op );
-
-void psPrintLine( wPos_t, wPos_t, wPos_t, wPos_t,
- wDrawWidth, wDrawLineType_e, wDrawColor, wDrawOpts );
-void psPrintArc( wPos_t, wPos_t, wPos_t, double, double, int,
- wDrawWidth, wDrawLineType_e, wDrawColor, wDrawOpts );
-void psPrintString( wPos_t x, wPos_t y, double a, char * s,
- wFont_p fp, double fs, wDrawColor color, wDrawOpts opts );
-
-void psPrintFillRectangle( wPos_t, wPos_t, wPos_t, wPos_t, wDrawColor, wDrawOpts );
-void psPrintFillPolygon( wPos_t [][2], int, wDrawColor, wDrawOpts );
-void psPrintFillCircle( wPos_t, wPos_t, wPos_t, wDrawColor, wDrawOpts );
+
+/* boxes.c */
+void wlibDrawBox(wWin_p win, wBoxType_e style, wPos_t x, wPos_t y, wPos_t w, wPos_t h);
+
+/* button.c */
+void wlibSetLabel(GtkWidget *widget, long option, const char *labelStr, GtkLabel **labelG, GtkWidget **imageG);
+void wlibButtonDoAction(wButton_p bb);
+
+struct wButton_t {
+ WOBJ_COMMON
+ GtkLabel * labelG;
+ GtkWidget * imageG;
+ wButtonCallBack_p action;
+ int busy;
+ int recursion;
+};
+
+/* color.c */
+typedef struct {
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+ GdkColor normalColor;
+ GdkColor invertColor;
+ long rgb;
+ int colorChar;
+} colorMap_t;
+
+GdkColor *wlibGetColor(wDrawColor color, wBool_t normal);
+
+/* control.c */
+
+/* droplist.c */
+enum columns {
+ LISTCOL_DATA, /**< user data not for display */
+ LISTCOL_BITMAP, /**< bitmap column */
+ LISTCOL_TEXT, /**< starting point for text columns */
+};
+GtkWidget *wlibNewDropList(GtkListStore *ls, int editable);
+
+wIndex_t wDropListGetCount(wList_p b);
+void wDropListClear(wList_p b);
+void *wDropListGetItemContext(wList_p b, wIndex_t inx);
+void wDropListAddValue(wList_p b, char *text, wListItem_p data);
+void wDropListSetIndex(wList_p b, int val);
+wBool_t wDropListSetValues(wList_p b, wIndex_t row, const char *labelStr, wIcon_p bm, void *itemData);
+wList_p wDropListCreate(wWin_p parent, wPos_t x, wPos_t y, const char *helpStr, const char *labelStr, long option, long number, wPos_t width, long *valueP, wListCallBack_p action, void *data);
+
+/* filesel.c */
+
+/* font.c */
+PangoLayout *wlibFontCreatePangoLayout(GtkWidget *widget, void *cairo, wFont_p fp, wFontSize_t fs, const char *s, int *width_p, int *height_p, int *ascent_p, int *descent_p);
+void wlibFontDestroyPangoLayout(PangoLayout *layout);
+const char *wlibFontTranslate(wFont_p fp);
+
+/* help.c */
+
+/* lines.c */
+void wlibLineShow(wLine_p bl, wBool_t visible);
+
+/* list.c */
+int CompareListData(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data);
+
+/* liststore.c */
+wListItem_p wlibListItemGet(GtkListStore *ls, wIndex_t inx, GList **childR);
+void *wlibListStoreGetContext(GtkListStore *ls, int inx);
+void wlibListStoreClear(GtkListStore *listStore);
+GtkListStore *wlibNewListStore(int colCnt);
+void wlibListStoreSetPixbuf(GtkListStore *ls, GtkTreeIter *iter, GdkPixbuf *pixbuf);
+int wlibListStoreAddData(GtkListStore *ls, GdkPixbuf *pixbuf, int cols, wListItem_p id);
+int wlibListStoreUpdateValues(GtkListStore *ls, int row, int cols, char *labels, wIcon_p bm);
+
+/* main.c */
+char *wlibGetAppName(void);
+
+/* menu.c */
+int getMlistOrigin(wMenuList_p ml, GList **pChildren);
+
+/* misc.c */
+typedef struct accelData_t {
+ wAccelKey_e key;
+ int modifier;
+ wAccelKeyCallBack_p action;
+ void * data;
+} accelData_t;
+
+
+GdkPixbuf* wlibPixbufFromXBM(wIcon_p ip);
+int wlibAddLabel(wControl_p b, const char *labelStr);
+void *wlibAlloc(wWin_p parent, wType_e type, wPos_t origX, wPos_t origY, const char *labelStr, int size, void *data);
+void wlibComputePos(wControl_p b);
+void wlibControlGetSize(wControl_p b);
+void wlibAddButton(wControl_p b);
+wControl_p wlibGetControlFromPos(wWin_p win, wPos_t x, wPos_t y);
+char *wlibConvertInput(const char *inString);
+char *wlibConvertOutput(const char *inString);
+struct accelData_t *wlibFindAccelKey(GdkEventKey *event);
+wBool_t wlibHandleAccelKey(GdkEventKey *event);
+
+/* notice.c */
+
+/* pixbuf.c */
+GdkPixbuf *wlibMakePixbuf(wIcon_p ip);
+
+/* png.c */
+
+/* print.c */
struct wDraw_t {
WOBJ_COMMON
void * context;
@@ -199,4 +268,48 @@ struct wDraw_t {
cairo_t *printContext;
cairo_surface_t *curPrintSurface;
};
+
+void WlibApplySettings(GtkPrintOperation *op);
+void WlibSaveSettings(GtkPrintOperation *op);
+void psPrintLine(wPos_t x0, wPos_t y0, wPos_t x1, wPos_t y1, wDrawWidth width, wDrawLineType_e lineType, wDrawColor color, wDrawOpts opts);
+void psPrintArc(wPos_t x0, wPos_t y0, wPos_t r, double angle0, double angle1, wBool_t drawCenter, wDrawWidth width, wDrawLineType_e lineType, wDrawColor color, wDrawOpts opts);
+void psPrintFillRectangle(wPos_t x0, wPos_t y0, wPos_t x1, wPos_t y1, wDrawColor color, wDrawOpts opts);
+void psPrintFillPolygon(wPos_t p[][2], int cnt, wDrawColor color, wDrawOpts opts);
+void psPrintFillCircle(wPos_t x0, wPos_t y0, wPos_t r, wDrawColor color, wDrawOpts opts);
+void psPrintString(wPos_t x, wPos_t y, double a, char *s, wFont_p fp, double fs, wDrawColor color, wDrawOpts opts);
+static void WlibGetPaperSize(void);
+
+/* single.c */
+
+/* splash.c */
+
+/* text.c */
+
+/* timer.c */
+void wlibSetTrigger(wControl_p b, setTriggerCallback_p trigger);
+
+/* tooltip.c */
+#define HELPDATAKEY "HelpDataKey"
+void wlibAddHelpString(GtkWidget *widget, const char *helpStr);
+void wlibHelpHideBalloon();
+
+/* treeview.c */
+void wlibTreeViewSetSelected(wList_p b, int index);
+GtkWidget *wlibNewTreeView(GtkListStore *ls, int showTitles, int multiSelection);
+int wlibTreeViewAddColumns(GtkWidget *tv, int count);
+int wlibAddColumnTitles(GtkWidget *tv, const char **titles);
+int wlibTreeViewAddData(GtkWidget *tv, int cols, char *label, GdkPixbuf *pixbuf, wListItem_p userData);
+void wlibTreeViewAddRow(wList_p b, char *label, wIcon_p bm, wListItem_p id_p);
+gboolean changeSelection(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer data);
+
+int wTreeViewGetCount(wList_p b);
+void wTreeViewClear(wList_p b);
+void *wTreeViewGetItemContext(wList_p b, int row);
+
+/* window.c */
+void wlibDoModal(wWin_p win0, wBool_t modal);
+wBool_t catch_shift_ctrl_alt_keys(GtkWidget *widget, GdkEventKey *event, void *data);
+
+/* wpref.c */
+
#endif
diff --git a/app/wlib/gtklib/gtklist.c b/app/wlib/gtklib/gtklist.c
deleted file mode 100644
index fb8afaa..0000000
--- a/app/wlib/gtklib/gtklist.c
+++ /dev/null
@@ -1,1131 +0,0 @@
-/** \file gtklist.c
- * Listboxes, dropdown boxes, combo boxes
- */
-/* 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 <stdlib.h>
-#include <string.h>
-
-#include <gtk/gtk.h>
-#include <gdk/gdk.h>
-#include "gtkint.h"
-#include "i18n.h"
-
-#define ROW_HEIGHT (15)
-#define PIX_TEXT_SEP (5)
-static char ListItemDataKey[] = "ListItemDataKey";
-
-/*
- *****************************************************************************
- *
- * List Boxes
- *
- *****************************************************************************
- */
-
-typedef struct wListItem_t * wListItem_p;
-
-struct wList_t {
- WOBJ_COMMON
- GtkWidget *list;
- int count;
- int number;
- int colCnt;
- wPos_t *colWidths;
- wBool_t *colRightJust;
- int last;
- wPos_t listX;
- long * valueP;
- wListCallBack_p action;
- int recursion;
- int editted;
- int editable;
- };
-
-
-struct wListItem_t {
- wBool_t active;
- void * itemData;
- const char * label;
- GtkLabel * labelG;
- wBool_t selected;
- wList_p listP;
- };
-
-
-static wListItem_p getListItem(
- wList_p b,
- wIndex_t inx,
- GList ** childR )
-{
- GList * child;
- GtkObject * listItem;
- wListItem_p id_p;
- if (childR)
- *childR = NULL;
- if (b->list == 0) abort();
- if (inx < 0)
- return NULL;
- if ( b->type == B_LIST )
- return (wListItem_p)gtk_clist_get_row_data( GTK_CLIST(b->list), inx );
-
- for ( child=GTK_LIST(b->list)->children; inx>0&&child; child=child->next,inx-- );
- if (child==NULL) {
- fprintf( stderr, "wListGetValues - End Of List\n" );
- return NULL;
- }
- listItem = GTK_OBJECT(child->data);
- id_p = (wListItem_p)gtk_object_get_data(listItem, ListItemDataKey );
- if (id_p==NULL) {
- fprintf( stderr, "wListGetValues - id_p == NULL\n" );
- return NULL;
- }
- if (childR)
- *childR = child;
- return id_p;
-}
-
-
-EXPORT void wListClear(
- wList_p b ) /* List */
-/*
-Remove all entries from the list <b>.
-*/
-{
- if (b->list == 0) abort();
- b->recursion++;
- if ( b->type == B_DROPLIST )
- gtk_list_clear_items( GTK_LIST(b->list), 0, b->count );
- else
- gtk_clist_clear( GTK_CLIST(b->list) );
- b->recursion--;
- b->last = -1;
- b->count = 0;
-}
-
-
-EXPORT void wListSetIndex(
- wList_p b, /* List */
- int val ) /* Index */
-/*
-Makes the <val>th entry (0-origin) the current selection.
-If <val> if '-1' then no entry is selected.
-*/
-{
- int cur;
- wListItem_p id_p;
-
- if (b->widget == 0) abort();
- b->recursion++;
- cur = b->last;
- if ( b->type == B_DROPLIST ) {
- if ((b->option&BL_NONE)!=0 && val < 0) {
- if (cur != -1) {
- gtk_list_unselect_item( GTK_LIST(b->list), cur );
- }
- } else {
- if (cur != -1)
- gtk_list_unselect_item( GTK_LIST(b->list), cur );
- if (val != -1)
- gtk_list_select_item( GTK_LIST(b->list), val );
- }
- } else {
- if (cur != -1) {
- gtk_clist_unselect_row( GTK_CLIST(b->list), cur, -1 );
- id_p = getListItem( b, cur, NULL );
- if ( id_p )
- id_p->selected = FALSE;
- }
- if (val != -1) {
- gtk_clist_select_row( GTK_CLIST(b->list), val, -1 );
- id_p = getListItem( b, val, NULL );
- if ( id_p )
- id_p->selected = TRUE;
- }
- }
- b->last = val;
- b->recursion--;
-}
-
-
-static void parseLabelStr(
- const char * labelStr,
- int count,
- char * * * texts )
-{
- static char * labelBuffer;
- static int labelBufferLen = 0;
- static char * * textBuffer;
- static int textBufferCount = 0;
- char * cp;
- int col;
- int len;
-
- labelStr = gtkConvertInput( labelStr );
- len = strlen(labelStr)+1;
- if ( len > labelBufferLen ) {
- if ( labelBuffer )
- labelBuffer = realloc( labelBuffer, len );
- else
- labelBuffer = (char*)malloc( len );
- labelBufferLen = len;
- }
- if ( count > textBufferCount ) {
- if ( textBuffer )
- textBuffer = (char**)malloc( count * sizeof *textBuffer );
- else
- textBuffer = (char**)realloc( textBuffer, count * sizeof *textBuffer );
- textBufferCount = count;
- }
-
- strcpy( labelBuffer, labelStr );
- cp = labelBuffer;
- for ( col=0; cp && col<count; col++ ) {
- textBuffer[col] = cp;
- cp = strchr( cp, '\t' );
- if ( cp != NULL )
- *cp++ = '\0';
- }
- for ( ; col<count; col++ )
- textBuffer[col] = "";
- *texts = textBuffer;
-}
-
-
-EXPORT void wListSetValue(
- wList_p bl,
- const char * val )
-{
- if (bl->list==NULL) abort();
- bl->recursion++;
- if (bl->type == B_DROPLIST) {
- bl->editted = TRUE;
- gtk_entry_set_text( GTK_ENTRY(GTK_COMBO(bl->widget)->entry), val );
- if (bl->action) {
- bl->action( -1, val, 0, bl->data, NULL );
- }
- }
- bl->recursion--;
-}
-
-
-EXPORT wIndex_t