summaryrefslogtreecommitdiff
path: root/app/bin/dlayer.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/dlayer.c')
-rw-r--r--app/bin/dlayer.c978
1 files changed, 978 insertions, 0 deletions
diff --git a/app/bin/dlayer.c b/app/bin/dlayer.c
new file mode 100644
index 0000000..17d787c
--- /dev/null
+++ b/app/bin/dlayer.c
@@ -0,0 +1,978 @@
+/** \file dlayer.c
+ * Functions and dialogs for handling layers.
+ *
+ * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/bin/dlayer.c,v 1.9 2009-06-15 19:29:57 m_fischer 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 <assert.h>
+
+#include "track.h"
+#include "i18n.h"
+
+#include <stdint.h>
+
+
+/*****************************************************************************
+ *
+ * LAYERS
+ *
+ */
+
+#define NUM_BUTTONS (20)
+#define LAYERPREF_FROZEN (1)
+#define LAYERPREF_ONMAP (2)
+#define LAYERPREF_VISIBLE (4)
+#define LAYERPREF_SECTION ("Layers")
+#define LAYERPREF_NAME "name"
+#define LAYERPREF_COLOR "color"
+#define LAYERPREF_FLAGS "flags"
+
+EXPORT LAYER_T curLayer;
+EXPORT long layerCount = 10;
+static long newLayerCount = 10;
+static LAYER_T layerCurrent = NUM_LAYERS;
+
+
+static BOOL_T layoutLayerChanged = FALSE;
+
+static wIcon_p show_layer_bmps[NUM_BUTTONS];
+/*static wIcon_p hide_layer_bmps[NUM_BUTTONS]; */
+static wButton_p layer_btns[NUM_BUTTONS]; /**< layer buttons on toolbar */
+
+/** Layer selector on toolbar */
+static wList_p setLayerL;
+
+/*static wMessage_p layerNumM;*/
+/** Describe the properties of a layer */
+typedef struct {
+ char name[STR_SHORT_SIZE]; /**< Layer name */
+ wDrawColor color; /**< layer color, is an index into a color table */
+ BOOL_T frozen; /**< Frozen flag */
+ BOOL_T visible; /**< visible flag */
+ BOOL_T onMap; /**< is layer shown map */
+ long objCount; /**< number of objects on layer */
+ } layer_t;
+
+static layer_t layers[NUM_LAYERS];
+static layer_t *layers_save = NULL;
+
+
+static int oldColorMap[][3] = {
+ { 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 */
+ };
+
+static void DoLayerOp( void * data );
+static void UpdateLayerDlg(void);
+/* static void LoadLayerLists(); */
+static void LayerSetCounts();
+static void InitializeLayers( void LayerInitFunc( void ), int newCurrLayer );
+static void LayerPrefSave( void );
+static void LayerPrefLoad( void );
+
+EXPORT BOOL_T GetLayerVisible( LAYER_T layer )
+{
+ if (layer < 0 || layer >= NUM_LAYERS)
+ return TRUE;
+ else
+ return layers[(int)layer].visible;
+}
+
+
+EXPORT BOOL_T GetLayerFrozen( LAYER_T layer )
+{
+ if (layer < 0 || layer >= NUM_LAYERS)
+ return TRUE;
+ else
+ return layers[(int)layer].frozen;
+}
+
+
+EXPORT BOOL_T GetLayerOnMap( LAYER_T layer )
+{
+ if (layer < 0 || layer >= NUM_LAYERS)
+ return TRUE;
+ else
+ return layers[(int)layer].onMap;
+}
+
+
+EXPORT char * GetLayerName( LAYER_T layer )
+{
+ if (layer < 0 || layer >= NUM_LAYERS)
+ return NULL;
+ else
+ return layers[(int)layer].name;
+}
+
+
+EXPORT void NewLayer( void )
+{
+}
+
+
+EXPORT wDrawColor GetLayerColor( LAYER_T layer )
+{
+ return layers[(int)layer].color;
+}
+
+
+static void FlipLayer( void * arg )
+{
+ LAYER_T l = (LAYER_T)(long)arg;
+ wBool_t visible;
+ if ( l < 0 || l >= NUM_LAYERS )
+ return;
+ if ( l == curLayer && layers[(int)l].visible) {
+ wButtonSetBusy( layer_btns[(int)l], layers[(int)l].visible );
+ NoticeMessage( MSG_LAYER_HIDE, _("Ok"), NULL );
+ return;
+ }
+ RedrawLayer( l, FALSE );
+ visible = !layers[(int)l].visible;
+ layers[(int)l].visible = visible;
+ if (l<NUM_BUTTONS) {
+ wButtonSetBusy( layer_btns[(int)l], visible != 0 );
+ wButtonSetLabel( layer_btns[(int)l], (char *)show_layer_bmps[(int)l]);
+ }
+ RedrawLayer( l, TRUE );
+}
+
+static void SetCurrLayer( wIndex_t inx, const char * name, wIndex_t op, void * listContext, void * arg )
+{
+ LAYER_T newLayer = (LAYER_T)(long)inx;
+ if (layers[(int)newLayer].frozen) {
+ NoticeMessage( MSG_LAYER_SEL_FROZEN, _("Ok"), NULL );
+ wListSetIndex( setLayerL, curLayer );
+ return;
+ }
+ curLayer = newLayer;
+
+ if ( curLayer < 0 || curLayer >= NUM_LAYERS )
+ curLayer = 0;
+ if ( !layers[(int)curLayer].visible )
+ FlipLayer( (void*)(intptr_t)inx );
+ if ( recordF )
+ fprintf( recordF, "SETCURRLAYER %d\n", inx );
+}
+
+static void PlaybackCurrLayer( char * line )
+{
+ wIndex_t layer;
+ layer = atoi(line);
+ wListSetIndex( setLayerL, layer );
+ SetCurrLayer( layer, NULL, 0, NULL, NULL );
+}
+
+/**
+ * Change the color of a layer.
+ *
+ * \param inx IN layer to change
+ * \param color IN new color
+ */
+
+static void SetLayerColor( int inx, wDrawColor color )
+{
+ if ( color != layers[inx].color ) {
+ if (inx < NUM_BUTTONS) {
+ wIconSetColor( show_layer_bmps[inx], color );
+ wButtonSetLabel( layer_btns[inx], (char*)show_layer_bmps[inx] );
+ }
+ layers[inx].color = color;
+ layoutLayerChanged = TRUE;
+ }
+}
+
+
+#include "bitmaps/l1.xbm"
+#include "bitmaps/l2.xbm"
+#include "bitmaps/l3.xbm"
+#include "bitmaps/l4.xbm"
+#include "bitmaps/l5.xbm"
+#include "bitmaps/l6.xbm"
+#include "bitmaps/l7.xbm"
+#include "bitmaps/l8.xbm"
+#include "bitmaps/l9.xbm"
+#include "bitmaps/l10.xbm"
+#include "bitmaps/l11.xbm"
+#include "bitmaps/l12.xbm"
+#include "bitmaps/l13.xbm"
+#include "bitmaps/l14.xbm"
+#include "bitmaps/l15.xbm"
+#include "bitmaps/l16.xbm"
+#include "bitmaps/l17.xbm"
+#include "bitmaps/l18.xbm"
+#include "bitmaps/l19.xbm"
+#include "bitmaps/l20.xbm"
+
+static char * show_layer_bits[NUM_BUTTONS] = { l1_bits, l2_bits, l3_bits, l4_bits, l5_bits, l6_bits, l7_bits, l8_bits, l9_bits, l10_bits,
+ l11_bits, l12_bits, l13_bits, l14_bits, l15_bits, l16_bits, l17_bits, l18_bits, l19_bits, l20_bits };
+
+static EXPORT long layerRawColorTab[] = {
+ wRGB( 0, 0,255), /* blue */
+ wRGB( 0, 0,128), /* dk blue */
+ wRGB( 0,128, 0), /* dk green */
+ wRGB(255,255, 0), /* yellow */
+ wRGB( 0,255, 0), /* green */
+ wRGB( 0,255,255), /* lt cyan */
+ wRGB(128, 0, 0), /* brown */
+ wRGB(128, 0,128), /* purple */
+ wRGB(128,128, 0), /* green-brown */
+ wRGB(255, 0,255)}; /* lt-purple */
+static EXPORT wDrawColor layerColorTab[COUNT(layerRawColorTab)];
+
+
+static wWin_p layerW;
+static char layerName[STR_SHORT_SIZE];
+static wDrawColor layerColor;
+static long layerVisible = TRUE;
+static long layerFrozen = FALSE;
+static long layerOnMap = TRUE;
+static void LayerOk( void * );
+static BOOL_T layerRedrawMap = FALSE;
+
+#define ENUMLAYER_RELOAD (1)
+#define ENUMLAYER_SAVE (2)
+#define ENUMLAYER_CLEAR (3)
+
+static char *visibleLabels[] = { "", NULL };
+static char *frozenLabels[] = { "", NULL };
+static char *onMapLabels[] = { "", NULL };
+static paramIntegerRange_t i0_20 = { 0, NUM_BUTTONS };
+
+static paramData_t layerPLs[] = {
+#define I_LIST (0)
+ { PD_DROPLIST, NULL, "layer", PDO_LISTINDEX|PDO_DLGNOLABELALIGN, (void*)250 },
+#define I_NAME (1)
+ { PD_STRING, layerName, "name", PDO_NOPREF, (void*)(250-54), N_("Name") },
+#define I_COLOR (2)
+ { PD_COLORLIST, &layerColor, "color", PDO_NOPREF, NULL, N_("Color") },
+#define I_VIS (3)
+ { PD_TOGGLE, &layerVisible, "visible", PDO_NOPREF, visibleLabels, N_("Visible"), BC_HORZ|BC_NOBORDER },
+#define I_FRZ (4)
+ { PD_TOGGLE, &layerFrozen, "frozen", PDO_NOPREF|PDO_DLGHORZ, frozenLabels, N_("Frozen"), BC_HORZ|BC_NOBORDER },
+#define I_MAP (5)
+ { PD_TOGGLE, &layerOnMap, "onmap", PDO_NOPREF|PDO_DLGHORZ, onMapLabels, N_("On Map"), BC_HORZ|BC_NOBORDER },
+#define I_COUNT (6)
+ { PD_STRING, NULL, "object-count", PDO_NOPREF|PDO_DLGBOXEND, (void*)(80), N_("Count"), BO_READONLY },
+ { PD_MESSAGE, N_("Personal Preferences"), NULL, PDO_DLGRESETMARGIN, (void *)180 },
+ { PD_BUTTON, (void*)DoLayerOp, "reset", PDO_DLGRESETMARGIN, 0, N_("Load"), 0, (void *)ENUMLAYER_RELOAD },
+ { PD_BUTTON, (void*)DoLayerOp, "save", PDO_DLGHORZ, 0, N_("Save"), 0, (void *)ENUMLAYER_SAVE },
+ { PD_BUTTON, (void*)DoLayerOp, "clear", PDO_DLGHORZ | PDO_DLGBOXEND, 0, N_("Defaults"), 0, (void *)ENUMLAYER_CLEAR },
+ { PD_LONG, &newLayerCount, "button-count", PDO_DLGBOXEND|PDO_DLGRESETMARGIN, &i0_20, N_("Number of Layer Buttons") },
+};
+
+static paramGroup_t layerPG = { "layer", 0, layerPLs, sizeof layerPLs/sizeof layerPLs[0] };
+
+#define layerL ((wList_p)layerPLs[I_LIST].control)
+
+/**
+ * Load the layer settings to hard coded system defaults
+ */
+
+void
+LayerSystemDefaults( void )
+{
+ int inx;
+
+ for ( inx=0;inx<NUM_LAYERS; inx++ ) {
+ strcpy( layers[inx].name, inx==0?_("Main"):"" );
+ layers[inx].visible = TRUE;
+ layers[inx].frozen = FALSE;
+ layers[inx].onMap = TRUE;
+ layers[inx].objCount = 0;
+ SetLayerColor( inx, layerColorTab[inx%COUNT(layerColorTab)] );
+ }
+}
+
+/**
+ * Load the layer listboxes in Manage Layers and the Toolbar with up-to-date information.
+ */
+
+EXPORT void LoadLayerLists( void )
+{
+ int inx;
+
+ /* clear both lists */
+ wListClear(setLayerL);
+ if ( layerL )
+ wListClear(layerL);
+
+ /* add all layers to both lists */
+ for ( inx=0; inx<NUM_LAYERS; inx++ ) {
+
+ if ( layerL ) {
+ sprintf( message, "%2d %c %s", inx+1, layers[inx].objCount>0?'+':'-', layers[inx].name );
+ wListAddValue( layerL, message, NULL, NULL );
+ }
+
+ sprintf( message, "%2d : %s", inx+1, layers[inx].name );
+ wListAddValue( setLayerL, message, NULL, NULL );
+ }
+
+ /* set current layer to selected */
+ wListSetIndex( setLayerL, curLayer );
+ if ( layerL )
+ wListSetIndex( layerL, curLayer );
+}
+
+/**
+ * Handle button presses for the layer dialog. For all button presses in the layer
+ * dialog, this function is called. The parameter identifies the button pressed and
+ * the operation is performed.
+ *
+ * \param[IN] data identifier for the button prerssed
+ * \return
+ */
+
+static void DoLayerOp( void * data )
+{
+ switch((long)data ) {
+
+ case ENUMLAYER_CLEAR:
+ InitializeLayers( LayerSystemDefaults, -1 );
+ break;
+ case ENUMLAYER_SAVE:
+ LayerPrefSave();
+ break;
+ case ENUMLAYER_RELOAD:
+ LayerPrefLoad();
+ break;
+ }
+
+ UpdateLayerDlg();
+ if( layoutLayerChanged ) {
+ MainProc( mainW, wResize_e, NULL );
+ layoutLayerChanged = FALSE;
+ changed = TRUE;
+ SetWindowTitle();
+ }
+}
+
+/**
+ * Update all dialogs and dialog elements after changing layers preferences. Once the global array containing
+ * the settings for the labels has been changed, this function needs to be called to update all the user interface
+ * elements to the new settings.
+ */
+
+static void
+UpdateLayerDlg()
+{
+ int inx;
+
+ /* update the globals for the layer dialog */
+ layerVisible = layers[curLayer].visible;
+ layerFrozen = layers[curLayer].frozen;
+ layerOnMap = layers[curLayer].onMap;
+ layerColor = layers[curLayer].color;
+ strcpy( layerName, layers[curLayer].name );
+ layerCurrent = curLayer;
+
+ /* now re-load the layer list boxes */
+ LoadLayerLists();
+
+ sprintf( message, "%ld", layers[curLayer].objCount );
+ ParamLoadMessage( &layerPG, I_COUNT, message );
+
+ /* force update of the 'manage layers' dialogbox */
+ if( layerL )
+ ParamLoadControls( &layerPG );
+
+ /* finally show the layer buttons with ballon text */
+ for( inx = 0; inx < NUM_BUTTONS; inx++ ) {
+ wButtonSetBusy( layer_btns[inx], layers[inx].visible != 0 );
+ wControlSetBalloonText( (wControl_p)layer_btns[inx], (layers[inx].name[0] != '\0' ? layers[inx].name :_("Show/Hide Layer") ));
+ }
+}
+
+/**
+ * Initialize the layer lists.
+ *
+ * \param IN pointer to function that actually initialize tha data structures
+ * \param IN current layer (0...NUM_LAYERS), (-1) for no change
+ */
+
+static void
+InitializeLayers( void LayerInitFunc( void ), int newCurrLayer )
+{
+ /* reset the data structures to default valuses */
+ LayerInitFunc();
+
+ /* count the objects on each layer */
+ LayerSetCounts();
+
+ /* Switch the current layer when requested */
+ if( newCurrLayer != -1 )
+ {
+ curLayer = newCurrLayer;
+ }
+}
+
+/**
+ * Save the customized layer information to preferences.
+ */
+
+static void
+LayerPrefSave( void )
+{
+ int inx;
+ int flags;
+ char buffer[ 80 ];
+ char layersSaved[ 3 * NUM_LAYERS ]; /* 0..99 plus separator */
+
+ /* FIXME: values for layers that are configured to default now should be overwritten in the settings */
+
+ layersSaved[ 0 ] = '\0';
+
+ for( inx = 0; inx < NUM_LAYERS; inx++ ) {
+ /* if a name is set that is not the default value or a color different from the default has been set,
+ information about the layer needs to be saved */
+ if( (layers[inx].name[0] && inx != 0 ) ||
+ layers[inx].frozen || (!layers[inx].onMap) || (!layers[inx].visible) ||
+ layers[inx].color != layerColorTab[inx%COUNT(layerColorTab)])
+ {
+ sprintf( buffer, LAYERPREF_NAME ".%0d", inx );
+ wPrefSetString( LAYERPREF_SECTION, buffer, layers[inx].name );
+
+ sprintf( buffer, LAYERPREF_COLOR ".%0d", inx );
+ wPrefSetInteger( LAYERPREF_SECTION, buffer, wDrawGetRGB(layers[inx].color));
+
+ flags = 0;
+ if( layers[inx].frozen )
+ flags |= LAYERPREF_FROZEN;
+ if( layers[inx].onMap )
+ flags |= LAYERPREF_ONMAP;
+ if( layers[inx].visible )
+ flags |= LAYERPREF_VISIBLE;
+
+ sprintf( buffer, LAYERPREF_FLAGS ".%0d", inx );
+ wPrefSetInteger( LAYERPREF_SECTION, buffer, flags );
+
+ /* extend the list of layers that are set up via the preferences */
+ if( layersSaved[ 0 ] )
+ strcat( layersSaved, "," );
+
+ sprintf( layersSaved, "%s%d", layersSaved, inx );
+ }
+ }
+
+ wPrefSetString( LAYERPREF_SECTION, "layers", layersSaved );
+}
+
+
+/**
+ * Load the settings for all layers from the preferences.
+ */
+
+static void
+LayerPrefLoad( void )
+{
+
+ int inx;
+ char layersSaved[ 3 * NUM_LAYERS ];
+ char layerOption[ 20 ];
+ const char *layerValue;
+ const char *prefString;
+ long rgb;
+ int color;
+ long flags;
+
+ /* reset layer preferences to system default */
+ LayerSystemDefaults();
+
+ prefString = wPrefGetString( LAYERPREF_SECTION, "layers" );
+ if( prefString && prefString[ 0 ] ) {
+ strncpy( layersSaved, prefString, sizeof( layersSaved ));
+ prefString = strtok( layersSaved, "," );
+ while( prefString ) {
+ inx = atoi( prefString );
+ sprintf( layerOption, LAYERPREF_NAME ".%d", inx );
+ layerValue = wPrefGetString( LAYERPREF_SECTION, layerOption );
+ if( layerValue )
+ strcpy( layers[inx].name, layerValue );
+ else
+ *(layers[inx].name) = '\0';
+
+ /* get and set the color, using the system default color in case color is not available from prefs */
+ sprintf( layerOption, LAYERPREF_COLOR ".%d", inx );
+ wPrefGetInteger( LAYERPREF_SECTION, layerOption, &rgb, layerColorTab[inx%COUNT(layerColorTab)] );
+ color = wDrawFindColor(rgb);
+ SetLayerColor( inx, color );
+
+ /* get and set the flags */
+ sprintf( layerOption, LAYERPREF_FLAGS ".%d", inx );
+ wPrefGetInteger( LAYERPREF_SECTION, layerOption, &flags, LAYERPREF_ONMAP | LAYERPREF_VISIBLE );
+
+ layers[inx].frozen = ((flags & LAYERPREF_FROZEN) != 0 );
+ layers[inx].onMap = ((flags & LAYERPREF_ONMAP) != 0 );
+ layers[inx].visible = (( flags & LAYERPREF_VISIBLE ) != 0 );
+
+ prefString = strtok( NULL, ",");
+ }
+ }
+}
+
+/**
+ * Count the number of elements on a layer.
+ * NOTE: This function has been implemented but not actually been tested. As it might prove useful in the
+ * future I left it in place. So you have been warned!
+ * \param IN layer to count
+ * \return number of elements
+ */
+/*
+static int LayerCount( int layer )
+{
+ track_p trk;
+ int inx;
+ int count = 0;
+
+ for( trk = NULL; TrackIterate(&trk); ) {
+ inx = GetTrkLayer( trk );
+ if( inx == layer )
+ count++;
+ }
+
+ return count;
+}
+*/
+
+/**
+ * Count the number of objects on each layer and store result in layers data structure.
+ */
+
+EXPORT void LayerSetCounts( void )
+{
+ int inx;
+ track_p trk;
+ for ( inx=0; inx<NUM_LAYERS; inx++ )
+ layers[inx].objCount = 0;
+ for ( trk=NULL; TrackIterate(&trk); ) {
+ inx = GetTrkLayer(trk);
+ if ( inx >= 0 && inx < NUM_LAYERS )
+ layers[inx].objCount++;
+ }
+}
+
+/**
+ * Reset layer options to their default values. The default values are loaded
+ * from the preferences file.
+ */
+
+EXPORT void
+DefaultLayerProperties(void)
+{
+ InitializeLayers( LayerPrefLoad, 0 );
+
+ UpdateLayerDlg();
+ if( layoutLayerChanged ) {
+ MainProc( mainW, wResize_e, NULL );
+ layoutLayerChanged = FALSE;
+ }
+}
+
+/**
+ * Update all UI elements after selecting a layer.
+ *
+ */
+
+static void LayerUpdate( void )
+{
+ BOOL_T redraw;
+ ParamLoadData( &layerPG );
+ if (layerCurrent < 0 || layerCurrent >= NUM_LAYERS)
+ return;
+ if (layerCurrent == curLayer && layerFrozen) {
+ NoticeMessage( MSG_LAYER_FREEZE, _("Ok"), NULL );
+ layerFrozen = FALSE;
+ ParamLoadControl( &layerPG, I_FRZ );
+ }
+ if (layerCurrent == curLayer && !layerVisible) {
+ NoticeMessage( MSG_LAYER_HIDE, _("Ok"), NULL );
+ layerVisible = TRUE;
+ ParamLoadControl( &layerPG, I_VIS );
+ }
+
+ if( strcmp( layers[(int)layerCurrent].name, layerName ) ||
+ layerColor != layers[(int)layerCurrent].color ||
+ layers[(int)layerCurrent].visible != (BOOL_T)layerVisible ||
+ layers[(int)layerCurrent].frozen != (BOOL_T)layerFrozen ||
+ layers[(int)layerCurrent].onMap != (BOOL_T)layerOnMap ) {
+
+ changed = TRUE;
+ SetWindowTitle();
+ }
+
+ if ( layerL ) {
+ strncpy( layers[(int)layerCurrent].name, layerName, sizeof layers[(int)layerCurrent].name );
+ sprintf( message, "%2d %c %s", (int)layerCurrent+1, layers[(int)layerCurrent].objCount>0?'+':'-', layers[(int)layerCurrent].name );
+ wListSetValues( layerL, layerCurrent, message, NULL, NULL );
+ }
+
+ sprintf( message, "%2d : %s", (int)layerCurrent+1, layers[(int)layerCurrent].name );
+ wListSetValues( setLayerL, layerCurrent, message, NULL, NULL );
+ if (layerCurrent < NUM_BUTTONS) {
+ if (strlen(layers[(int)layerCurrent].name)>0)
+ wControlSetBalloonText( (wControl_p)layer_btns[(int)layerCurrent], layers[(int)layerCurrent].name );
+ else
+ wControlSetBalloonText( (wControl_p)layer_btns[(int)layerCurrent], _("Show/Hide Layer") );
+ }
+ redraw = ( layerColor != layers[(int)layerCurrent].color ||
+ (BOOL_T)layerVisible != layers[(int)layerCurrent].visible );
+ if ( (!layerRedrawMap) && redraw)
+ RedrawLayer( (LAYER_T)layerCurrent, FALSE );
+
+ SetLayerColor( layerCurrent, layerColor );
+
+ if (layerCurrent<NUM_BUTTONS && layers[(int)layerCurrent].visible!=(BOOL_T)layerVisible) {
+ wButtonSetBusy( layer_btns[(int)layerCurrent], layerVisible );
+ }
+ layers[(int)layerCurrent].visible = (BOOL_T)layerVisible;
+ layers[(int)layerCurrent].frozen = (BOOL_T)layerFrozen;
+ layers[(int)layerCurrent].onMap = (BOOL_T)layerOnMap;
+ if ( layerRedrawMap )
+ DoRedraw();
+ else if (redraw)
+ RedrawLayer( (LAYER_T)layerCurrent, TRUE );
+ layerRedrawMap = FALSE;
+}
+
+
+static void LayerSelect(
+ wIndex_t inx )
+{
+ LayerUpdate();
+ if (inx < 0 || inx >= NUM_LAYERS)
+ return;
+ layerCurrent = (LAYER_T)inx;
+ strcpy( layerName, layers[inx].name );
+ layerVisible = layers[inx].visible;
+ layerFrozen = layers[inx].frozen;
+ layerOnMap = layers[inx].onMap;
+ layerColor = layers[inx].color;
+ sprintf( message, "%ld", layers[inx].objCount );
+
+ ParamLoadMessage( &layerPG, I_COUNT, message );
+ ParamLoadControls( &layerPG );
+}
+
+EXPORT void ResetLayers( void )
+{
+ int inx;
+ for ( inx=0;inx<NUM_LAYERS; inx++ ) {
+ strcpy( layers[inx].name, inx==0?_("Main"):"" );
+ layers[inx].visible = TRUE;
+ layers[inx].frozen = FALSE;
+ layers[inx].onMap = TRUE;
+ layers[inx].objCount = 0;
+ SetLayerColor( inx, layerColorTab[inx%COUNT(layerColorTab)] );
+ if ( inx<NUM_BUTTONS ) {
+ wButtonSetLabel( layer_btns[inx], (char*)show_layer_bmps[inx] );
+ }
+ }
+ wControlSetBalloonText( (wControl_p)layer_btns[0], _("Main") );
+ for ( inx=1; inx<NUM_BUTTONS; inx++ ) {
+ wControlSetBalloonText( (wControl_p)layer_btns[inx], _("Show/Hide Layer") );
+ }
+ curLayer = 0;
+ layerVisible = TRUE;
+ layerFrozen = FALSE;
+ layerOnMap = TRUE;
+ layerColor = layers[0].color;
+ strcpy( layerName, layers[0].name );
+ LoadLayerLists();
+
+ if (layerL) {
+ ParamLoadControls( &layerPG );
+ ParamLoadMessage( &layerPG, I_COUNT, "0" );
+ }
+}
+
+
+EXPORT void SaveLayers( void )
+{
+ layers_save = malloc( NUM_LAYERS * sizeof( layer_t ));
+ assert( layers_save != NULL );
+
+ memcpy( layers_save, layers, NUM_LAYERS * sizeof layers[0] );
+ ResetLayers();
+}
+
+EXPORT void RestoreLayers( void )
+{
+ int inx;
+ char * label;
+ wDrawColor color;
+
+ assert( layers_save != NULL );
+ memcpy( layers, layers_save, NUM_LAYERS * sizeof layers[0] );
+ free( layers_save );
+
+ for ( inx=0; inx<NUM_BUTTONS; inx++ ) {
+ color = layers[inx].color;
+ layers[inx].color = -1;
+ SetLayerColor( inx, color );
+ if ( layers[inx].name[0] == '\0' ) {
+ if ( inx == 0 ) {
+ label = _("Main");
+ } else {
+ label = _("Show/Hide Layer");
+ }
+ } else {
+ label = layers[inx].name;
+ }
+ wControlSetBalloonText( (wControl_p)layer_btns[inx], label );
+ }
+ if (layerL) {
+ ParamLoadControls( &layerPG );
+ ParamLoadMessage( &layerPG, I_COUNT, "0" );
+ }
+ LoadLayerLists();
+}
+
+/**
+ * This function is called when the Done button on the layer dialog is pressed. It hides the layer dialog and
+ * updates the layer information.
+ *
+ * \param IN ignored
+ *
+ */
+
+static void LayerOk( void * junk )
+{
+ LayerSelect( layerCurrent );
+
+ if (newLayerCount != layerCount) {
+ layoutLayerChanged = TRUE;
+ if ( newLayerCount > NUM_BUTTONS )
+ newLayerCount = NUM_BUTTONS;
+ layerCount = newLayerCount;
+ }
+ if (layoutLayerChanged)
+ MainProc( mainW, wResize_e, NULL );
+ wHide( layerW );
+}
+
+
+static void LayerDlgUpdate(
+ paramGroup_p pg,
+ int inx,
+ void * valueP )
+{
+ switch (inx) {
+ case I_LIST:
+ LayerSelect( (wIndex_t)*(long*)valueP );
+ break;
+ case I_NAME:
+ LayerUpdate();
+ break;
+ case I_MAP:
+ layerRedrawMap = TRUE;
+ break;
+ }
+}
+
+
+static void DoLayer( void * junk )
+{
+ if (layerW == NULL)
+ layerW = ParamCreateDialog( &layerPG, MakeWindowTitle(_("Layers")), _("Done"), LayerOk, NULL, TRUE, NULL, 0, LayerDlgUpdate );
+
+ /* set the globals to the values for the current layer */
+ UpdateLayerDlg();
+
+ layerRedrawMap = FALSE;
+ wShow( layerW );
+
+ layoutLayerChanged = FALSE;
+}
+
+
+EXPORT BOOL_T ReadLayers( char * line )
+{
+ char * name;
+ int inx, visible, frozen, color, onMap;
+ long rgb;
+
+ /* older files didn't support layers */
+
+ if (paramVersion < 7)
+ return TRUE;
+
+ /* set the current layer */
+
+ if ( strncmp( line, "CURRENT", 7 ) == 0 ) {
+ curLayer = atoi( line+7 );
+ if ( curLayer < 0 )
+ curLayer = 0;
+
+ if (layerL)
+ wListSetIndex( layerL, curLayer );
+ if (setLayerL)
+ wListSetIndex( setLayerL, curLayer );
+
+ return TRUE;
+ }
+
+ /* get the properties for a layer from the file and update the layer accordingly */
+
+ if (!GetArgs( line, "ddddl0000q", &inx, &visible, &frozen, &onMap, &rgb, &name ))
+ return FALSE;
+ if (paramVersion < 9) {
+ if ( rgb >= 0 && (int)rgb < sizeof oldColorMap/sizeof oldColorMap[0] )
+ rgb = wRGB( oldColorMap[(int)rgb][0], oldColorMap[(int)rgb][1], oldColorMap[(int)rgb][2] );
+ else
+ rgb = 0;
+ }
+ if (inx < 0 || inx >= NUM_LAYERS)
+ return FALSE;
+ color = wDrawFindColor(rgb);
+ SetLayerColor( inx, color );
+ strncpy( layers[inx].name, name, sizeof layers[inx].name );
+ layers[inx].visible = visible;
+ layers[inx].frozen = frozen;
+ layers[inx].onMap = onMap;
+ layers[inx].color = color;
+ if (inx<NUM_BUTTONS) {
+ if (strlen(name) > 0) {
+ wControlSetBalloonText( (wControl_p)layer_btns[(int)inx], layers[inx].name );
+ }
+ wButtonSetBusy( layer_btns[(int)inx], visible );
+ }
+ return TRUE;
+}
+
+
+EXPORT BOOL_T WriteLayers( FILE * f )
+{
+ int inx;
+ BOOL_T rc = TRUE;
+ for (inx=0; inx<NUM_LAYERS; inx++)
+ if ((!layers[inx].visible) || layers[inx].frozen || (!layers[inx].onMap) ||
+ layers[inx].color!=layerColorTab[inx%(COUNT(layerColorTab))] ||
+ layers[inx].name[0] )
+ rc &= fprintf( f, "LAYERS %d %d %d %d %ld %d %d %d %d \"%s\"\n", inx, layers[inx].visible, layers[inx].frozen, layers[inx].onMap, wDrawGetRGB(layers[inx].color), 0, 0, 0, 0, PutTitle(layers[inx].name) )>0;
+ rc &= fprintf( f, "LAYERS CURRENT %d\n", curLayer )>0;
+ return TRUE;
+}
+
+
+EXPORT void InitLayers( void )
+{
+ int i;
+
+ wPrefGetInteger( PREFSECT, "layer-button-count", &layerCount, layerCount );
+ for ( i = 0; i<COUNT(layerRawColorTab); i++ )
+ layerColorTab[i] = wDrawFindColor( layerRawColorTab[i] );
+
+ /* create the bitmaps for the layer buttons */
+ for ( i = 0; i<NUM_BUTTONS; i++ ) {
+ show_layer_bmps[i] = wIconCreateBitMap( l1_width, l1_height, show_layer_bits[i], layerColorTab[i%(COUNT(layerColorTab))] );
+ layers[i].color = layerColorTab[i%(COUNT(layerColorTab))];
+ }
+
+ /* layer list for toolbar */
+ setLayerL = wDropListCreate( mainW, 0, 0, "cmdLayerSet", NULL, 0, 10, 200, NULL, SetCurrLayer, NULL );
+ wControlSetBalloonText( (wControl_p)setLayerL, GetBalloonHelpStr("cmdLayerSet") );
+ AddToolbarControl( (wControl_p)setLayerL, IC_MODETRAIN_TOO );
+
+ for ( i = 0; i<NUM_LAYERS; i++ ) {
+ if (i<NUM_BUTTONS) {
+ /* create the layer button */
+ sprintf( message, "cmdLayerShow%d", i );
+ layer_btns[i] = wButtonCreate( mainW, 0, 0, message,
+ (char*)(show_layer_bmps[i]),
+ BO_ICON, 0, (wButtonCallBack_p)FlipLayer, (void*)(intptr_t)i );
+
+ /* add the help text */
+ wControlSetBalloonText( (wControl_p)layer_btns[i], _("Show/Hide Layer") );
+
+ /* put on toolbar */
+ AddToolbarControl( (wControl_p)layer_btns[i], IC_MODETRAIN_TOO );
+
+ /* set state of button */
+ wButtonSetBusy( layer_btns[i], 1 );
+ }
+ sprintf( message, "%2d : %s", i+1, (i==0?_("Main"):"") );
+ wListAddValue( setLayerL, message, NULL, (void*)(intptr_t)i );
+ }
+ AddPlaybackProc( "SETCURRLAYER", PlaybackCurrLayer, NULL );
+ AddPlaybackProc( "LAYERS", (playbackProc_p)ReadLayers, NULL );
+}
+
+
+EXPORT addButtonCallBack_t InitLayersDialog( void ) {
+ ParamRegister( &layerPG );
+ return &DoLayer;
+}