summaryrefslogtreecommitdiff
path: root/app/bin/layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/layout.c')
-rw-r--r--app/bin/layout.c364
1 files changed, 348 insertions, 16 deletions
diff --git a/app/bin/layout.c b/app/bin/layout.c
index 584e62b..a77cbb2 100644
--- a/app/bin/layout.c
+++ b/app/bin/layout.c
@@ -31,6 +31,8 @@
#include "paths.h"
#include "track.h"
#include "wlib.h"
+#include "fileio.h"
+#include "utility.h"
#define MINTRACKRADIUSPREFS "minTrackRadius"
@@ -43,6 +45,11 @@ struct sLayoutProps {
DIST_T minTrackRadius;
DIST_T maxTrackGrade;
coOrd roomSize;
+ DynString backgroundFileName;
+ coOrd backgroundPos;
+ ANGLE_T backgroundAngle;
+ int backgroundScreen;
+ double backgroundSize;
};
struct sDataLayout {
@@ -51,8 +58,8 @@ struct sDataLayout {
struct sLayoutProps *copyOfLayoutProps;
};
-struct sDataLayout thisLayout = {
- { "", "", -1, 0, 0, 0.0, 5.0, {0.0, 0.0} },
+static struct sDataLayout thisLayout = {
+ { "", "", -1, 0, 0, 0.0, 5.0, {0.0, 0.0}, NaS, {0.0, 0.0}, 0.0, 0, 0.0 },
NaS,
NULL,
};
@@ -60,6 +67,9 @@ struct sDataLayout thisLayout = {
static paramFloatRange_t r0_90 = { 0, 90 };
static paramFloatRange_t r1_10000 = { 1, 10000 };
static paramFloatRange_t r1_9999999 = { 1, 9999999 };
+static paramFloatRange_t r360_360 = { -360, 360 };
+static paramFloatRange_t rN_9999999 = { -99999, 99999 };
+static paramIntegerRange_t i0_100 = { 0, 100 };
static void LayoutDlgUpdate(paramGroup_p pg, int inx, void * valueP);
@@ -72,14 +82,18 @@ static void LayoutDlgUpdate(paramGroup_p pg, int inx, void * valueP);
void
SetLayoutFullPath(const char *fileName)
{
- if (DynStringToCStr(&thisLayout.fullFileName) != fileName) {
- if (isnas(&thisLayout.fullFileName)) {
- DynStringMalloc(&thisLayout.fullFileName, strlen(fileName) + 1);
- } else {
- DynStringClear(&thisLayout.fullFileName);
- }
-
- DynStringCatCStr(&thisLayout.fullFileName, fileName);
+ if (fileName && fileName[0]) {
+ if (DynStringSize(&thisLayout.fullFileName)) {
+ if (strcmp(DynStringToCStr(&thisLayout.fullFileName),fileName)==0) {
+ return;
+ }
+ DynStringClear(&thisLayout.fullFileName);
+ }
+ DynStringMalloc(&thisLayout.fullFileName, strlen(fileName) + 1);
+ DynStringCatCStr(&thisLayout.fullFileName, fileName);
+ } else {
+ DynStringMalloc(&thisLayout.fullFileName, 2);
+ DynStringCatCStr(&thisLayout.fullFileName, "");
}
}
@@ -157,6 +171,41 @@ SetLayoutCurGauge(GAUGEINX_T gauge)
thisLayout.props.curGaugeInx = gauge;
}
+void SetLayoutBackGroundFullPath(const char *fileName) {
+ if (fileName && fileName[0]) {
+ if (DynStringSize(&thisLayout.props.backgroundFileName)) {
+ if (strcmp(DynStringToCStr(&thisLayout.props.backgroundFileName),fileName)==0) {
+ return;
+ }
+ DynStringClear(&thisLayout.props.backgroundFileName);
+ }
+ DynStringMalloc(&thisLayout.props.backgroundFileName, strlen(fileName) + 1);
+ DynStringCatCStr(&thisLayout.props.backgroundFileName, fileName);
+ } else {
+ DynStringClear(&thisLayout.props.backgroundFileName);
+ DynStringCatCStr(&thisLayout.props.backgroundFileName, "");
+ }
+}
+
+void SetLayoutBackGroundSize(double size) {
+ thisLayout.props.backgroundSize = size;
+}
+
+void SetLayoutBackGroundPos(coOrd pos) {
+ thisLayout.props.backgroundPos = pos;
+
+}
+
+void SetLayoutBackGroundAngle(ANGLE_T angle) {
+ thisLayout.props.backgroundAngle = angle;
+
+}
+
+void SetLayoutBackGroundScreen(int screen) {
+ thisLayout.props.backgroundScreen = screen;
+
+}
+
/**
* Return the full filename.
*
@@ -166,7 +215,8 @@ SetLayoutCurGauge(GAUGEINX_T gauge)
char *
GetLayoutFullPath()
{
- return (DynStringToCStr(&thisLayout.fullFileName));
+ char * s = DynStringToCStr(&thisLayout.fullFileName);
+ return s;
}
/**
@@ -181,7 +231,7 @@ GetLayoutFilename()
char *string = DynStringToCStr(&thisLayout.fullFileName);
if (string) {
- return (FindFilename(string));
+ return FindFilename(string);
} else {
return (NULL);
}
@@ -222,14 +272,188 @@ GetLayoutCurScale()
{
return (thisLayout.props.curScaleInx);
}
+
+char *
+GetLayoutBackGroundFullPath()
+{
+ char * s = DynStringToCStr(&thisLayout.props.backgroundFileName);
+ return s;
+}
+
+double
+GetLayoutBackGroundSize()
+{
+ if (thisLayout.props.backgroundSize > 0.0) {
+ return (thisLayout.props.backgroundSize);
+ } else {
+ return (thisLayout.props.roomSize.x);
+ }
+}
+
+coOrd
+GetLayoutBackGroundPos()
+{
+ return (thisLayout.props.backgroundPos);
+}
+
+ANGLE_T
+GetLayoutBackGroundAngle()
+{
+ return (thisLayout.props.backgroundAngle);
+}
+
+int GetLayoutBackGroundScreen()
+{
+ return (thisLayout.props.backgroundScreen);
+}
+
/****************************************************************************
*
* Layout Dialog
*
*/
+static char backgroundFileName[STR_LONG_SIZE];
+#define TEXT_FIELD_LEN 40
static wWin_p layoutW;
+/**************************************************************************************
+* Show only the end of the background file path including the filename in the Dialog
+*/
+void SetName() {
+ char * name = GetLayoutBackGroundFullPath();
+ if (name && name[0]) { //Ignore ""
+ if (name && (strlen(name)<=TEXT_FIELD_LEN)) {
+ for (unsigned int i=0; i<=strlen(name);i++) {
+ backgroundFileName[i] = name[i];
+ }
+ backgroundFileName[strlen(name)] = '\0';
+ } else {
+ for (int i=TEXT_FIELD_LEN;i>=0; i--) {
+ backgroundFileName[i] = name[strlen(name)-(TEXT_FIELD_LEN-i)];
+ }
+ backgroundFileName[TEXT_FIELD_LEN] = '\0'; //Insurance
+ }
+ } else backgroundFileName[0] = '\0';
+}
+
+static struct wFilSel_t * imageFile_fs;
+
+static paramData_p layout_p;
+static paramGroup_t * layout_pg_p;
+static wBool_t file_changed;
+
+EXPORT BOOL_T haveBackground = FALSE;
+BOOL_T backgroundVisible = TRUE;
+
+char * noname = "";
+
+void
+BackgroundToggleShow()
+{
+ backgroundVisible = !backgroundVisible;
+ wButtonSetBusy(backgroundB, backgroundVisible);
+ MainRedraw();
+}
+
+int GetLayoutBackGroundVisible()
+{
+ return(backgroundVisible);
+}
+
+/*****************************************
+* Try to load the background image file
+*/
+wBool_t
+LoadBackGroundImage(void)
+{
+ char * error;
+ char * background = GetLayoutBackGroundFullPath();
+ if (wDrawSetBackground( mainD.d, background, &error)==-1) {
+ NoticeMessage(_("Unable to load Image File - %s"),_("Ok"),NULL,error);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*******************************************************
+* Callback from File Select for Background Image File
+*
+* \param files number of files selected (only first file is used)
+* \param fileName array of pointers to filenames
+* \param data unused
+* \return FALSE
+*/
+EXPORT int LoadImageFile(
+ int files,
+ char ** fileName,
+ void * data )
+{
+ if (files >0) {
+ SetLayoutBackGroundFullPath( strdup(fileName[0]));
+
+ if (!LoadBackGroundImage()) {
+ SetLayoutBackGroundFullPath(noname);
+ backgroundVisible = FALSE;
+ }
+ else {
+ backgroundVisible = TRUE;
+ SetCurrentPath(BACKGROUNDPATHKEY, fileName[0]);
+ }
+ } else {
+ SetLayoutBackGroundFullPath(noname);
+ backgroundVisible = FALSE;
+ }
+ wControlActive((wControl_p)backgroundB, backgroundVisible);
+ wButtonSetBusy(backgroundB, backgroundVisible);
+
+ SetName();
+ file_changed = TRUE;
+ ParamLoadControl(layout_pg_p, 8);
+ return FALSE;
+}
+
+/**********************************************************
+ * Save the Background Parms - forcing a write
+ */
+void LayoutBackGroundSave(void) {
+ char * background = GetLayoutBackGroundFullPath();
+ wPrefSetString("layout", "BackgroundPath", background);
+ wPrefSetFloat("layout", "BackgroundPosX", thisLayout.props.backgroundPos.x);
+ wPrefSetFloat("layout", "BackgroundPosY", thisLayout.props.backgroundPos.y);
+ wPrefSetFloat("layout", "BackgroundAngle", thisLayout.props.backgroundAngle);
+ wPrefSetInteger("layout", "BackgroundScreen", thisLayout.props.backgroundScreen);
+ wPrefSetFloat("layout", "BackgroundSize", thisLayout.props.backgroundSize);
+
+ wPrefFlush();
+}
+
+/************************************************************
+ * Run File Select for the Background Image File
+ */
+static void ImageFileBrowse( void * junk )
+{
+ imageFile_fs = wFilSelCreate( mainW, FS_LOAD, FS_PICTURES, _("Load Background"), sImageFilePattern, LoadImageFile, NULL );
+
+ wFilSelect( imageFile_fs, GetCurrentPath( BACKGROUNDPATHKEY ) );
+ return;
+}
+
+/************************************************************
+ * Remove the background Image File
+ */
+static void ImageFileClear( void * junk)
+{
+ char * noname = "";
+ SetLayoutBackGroundFullPath(noname);
+ wDrawSetBackground( mainD.d, NULL, NULL);
+ SetName();
+ wControlActive((wControl_p)backgroundB, FALSE);
+ file_changed = TRUE;
+ ParamLoadControl(layout_pg_p, 8);
+ MainRedraw();
+}
+
static paramData_t layoutPLs[] = {
{ PD_FLOAT, &thisLayout.props.roomSize.x, "roomsizeX", PDO_NOPREF | PDO_DIM | PDO_NOPSHUPD | PDO_DRAW, &r1_9999999, N_("Room Width"), 0, (void*)(CHANGE_MAIN | CHANGE_MAP) },
{ PD_FLOAT, &thisLayout.props.roomSize.y, "roomsizeY", PDO_NOPREF | PDO_DIM | PDO_NOPSHUPD | PDO_DRAW | PDO_DLGHORZ, &r1_9999999, N_(" Height"), 0, (void*)(CHANGE_MAIN | CHANGE_MAP) },
@@ -241,7 +465,22 @@ static paramData_t layoutPLs[] = {
{ PD_DROPLIST, &thisLayout.props.curGaugeInx, "gauge", PDO_NOPREF | PDO_NOPSHUPD | PDO_NORECORD | PDO_NOUPDACT | PDO_DLGHORZ, (void *)120, N_(" Gauge"), 0, (void *)(CHANGE_SCALE) },
#define MINRADIUSENTRY (6)
{ PD_FLOAT, &thisLayout.props.minTrackRadius, "mintrackradius", PDO_DIM | PDO_NOPSHUPD | PDO_NOPREF, &r1_10000, N_("Min Track Radius"), 0, (void*)(CHANGE_MAIN | CHANGE_LIMITS) },
- { PD_FLOAT, &thisLayout.props.maxTrackGrade, "maxtrackgrade", PDO_NOPSHUPD | PDO_DLGHORZ, &r0_90, N_(" Max Track Grade (%)"), 0, (void*)(CHANGE_MAIN) }
+ { PD_FLOAT, &thisLayout.props.maxTrackGrade, "maxtrackgrade", PDO_NOPSHUPD | PDO_DLGHORZ, &r0_90, N_(" Max Track Grade (%)"), 0, (void*)(CHANGE_MAIN) },
+#define BACKGROUNDFILEENTRY (8) //Note this value used in the file section routines above - if it chnages, they will need to change
+ { PD_STRING, &backgroundFileName, "backgroundfile", PDO_NOPSHUPD, NULL, N_("Background File Path"), 0, (void *)(CHANGE_BACKGROUND) },
+ { PD_BUTTON, (void*)ImageFileBrowse, "browse", PDO_DLGHORZ, NULL, N_("Browse ...") },
+ { PD_BUTTON, (void*)ImageFileClear, "clear", PDO_DLGHORZ, NULL, N_("Clear") },
+#define BACKGROUNDPOSX (11)
+ { PD_FLOAT, &thisLayout.props.backgroundPos.x, "backgroundposX", PDO_DIM | PDO_NOPSHUPD | PDO_DRAW, &rN_9999999, N_("Background PosX,Y"), 0, (void*)(CHANGE_BACKGROUND) },
+#define BACKGROUNDPOSY (12)
+ { PD_FLOAT, &thisLayout.props.backgroundPos.y, "backgroundposY", PDO_DIM | PDO_NOPSHUPD | PDO_DRAW | PDO_DLGHORZ, &rN_9999999, NULL, 0, (void*)(CHANGE_BACKGROUND) },
+#define BACKGROUNDWIDTH (13)
+ { PD_FLOAT, &thisLayout.props.backgroundSize, "backgroundWidth", PDO_DIM | PDO_NOPSHUPD | PDO_DRAW, &r1_9999999, N_("Background Size"), 0, (void*)(CHANGE_BACKGROUND) },
+#define BACKGROUNDSCREEN (14)
+ { PD_LONG, &thisLayout.props.backgroundScreen, "backgroundScreen", PDO_NOPSHUPD | PDO_DRAW, &i0_100, N_("Background Screen %"), 0, (void*)(CHANGE_BACKGROUND) },
+#define BACKGROUNDANGLE (15)
+ { PD_FLOAT, &thisLayout.props.backgroundAngle, "backgroundAngle", PDO_NOPSHUPD | PDO_DRAW, &r360_360, N_("Background Angle"), 0, (void*)(CHANGE_BACKGROUND) }
+
};
static paramGroup_t layoutPG = { "layout", PGO_RECORD | PGO_PREFMISC, layoutPLs, sizeof layoutPLs / sizeof layoutPLs[0] };
@@ -278,10 +517,20 @@ static void LayoutOk(void * junk)
wPrefSetFloat("misc", prefString, thisLayout.props.minTrackRadius);
}
+ if ((changes & CHANGE_BACKGROUND) || file_changed) {
+
+ LayoutBackGroundSave();
+ file_changed = FALSE;
+ }
+
free(thisLayout.copyOfLayoutProps);
wHide(layoutW);
+
+ MainLayout( TRUE, TRUE );
}
+
+
/**
* Discard the changes entered and replace with earlier values
*
@@ -297,7 +546,7 @@ static void LayoutCancel(struct wWin_t *junk)
static void LayoutChange(long changes)
{
- if (changes & (CHANGE_SCALE | CHANGE_UNITS))
+ if (changes & (CHANGE_SCALE | CHANGE_UNITS | CHANGE_BACKGROUND))
if (layoutW != NULL && wWinIsVisible(layoutW)) {
ParamLoadControls(&layoutPG);
}
@@ -305,7 +554,7 @@ static void LayoutChange(long changes)
void DoLayout(void * junk)
{
- thisLayout.props.roomSize = mapD.size;
+ SetLayoutRoomSize(mapD.size);
if (layoutW == NULL) {
layoutW = ParamCreateDialog(&layoutPG, MakeWindowTitle(_("Layout Options")),
@@ -313,6 +562,8 @@ void DoLayout(void * junk)
LoadScaleList((wList_p)layoutPLs[4].control);
}
+ ParamControlActive(&layoutPG, BACKGROUNDFILEENTRY, FALSE);
+
LoadGaugeList((wList_p)layoutPLs[5].control,
thisLayout.props.curScaleDescInx); /* set correct gauge list here */
thisLayout.copyOfLayoutProps = malloc(sizeof(struct sLayoutProps));
@@ -320,7 +571,7 @@ void DoLayout(void * junk)
if (!thisLayout.copyOfLayoutProps) {
exit(1);
}
-
+ SetName();
*(thisLayout.copyOfLayoutProps) = thisLayout.props;
ParamLoadControls(&layoutPG);
@@ -331,6 +582,8 @@ EXPORT addButtonCallBack_t LayoutInit(void)
{
ParamRegister(&layoutPG);
RegisterChangeNotification(LayoutChange);
+ layout_p = layoutPLs;
+ layout_pg_p = &layoutPG;
return &DoLayout;
}
@@ -372,4 +625,83 @@ LayoutDlgUpdate(
wStringSetValue((wString_p)layoutPLs[MINRADIUSENTRY].control,
FormatDistance(thisLayout.props.minTrackRadius));
}
+ if (inx == BACKGROUNDPOSX) {
+ coOrd pos;
+ pos.x = *(double *)valueP;
+ pos.y = GetLayoutBackGroundPos().y;
+ SetLayoutBackGroundPos(pos);
+ MainRedraw();
+ }
+ if (inx == BACKGROUNDPOSY) {
+ coOrd pos;
+ pos.y = *(double *)valueP;
+ pos.x = GetLayoutBackGroundPos().x;
+ SetLayoutBackGroundPos(pos);
+ MainRedraw();
+ }
+ if (inx == BACKGROUNDWIDTH) {
+ SetLayoutBackGroundSize(*(double *)valueP);
+ MainRedraw();
+ }
+ if (inx == BACKGROUNDSCREEN) {
+ SetLayoutBackGroundScreen(*(int *)valueP);
+ MainRedraw();
+ }
+ if (inx == BACKGROUNDANGLE) {
+
+ ANGLE_T angle = NormalizeAngle(*(double *)valueP);
+ wStringSetValue((wString_p)layoutPLs[BACKGROUNDANGLE].control,FormatFloat(angle));
+ SetLayoutBackGroundAngle(angle);
+ MainRedraw();
+ }
+
+}
+/***************************************************************************************
+ * Load Background Options from Saved Parms
+ ***************************************************************************************/
+void
+LayoutBackGroundLoad(void) {
+ SetLayoutBackGroundFullPath(wPrefGetString("layout", "BackgroundPath"));
+
+ wPrefGetFloat("layout", "BackgroundPosX", &thisLayout.props.backgroundPos.x, 0.0);
+ wPrefGetFloat("layout", "BackgroundPosY", &thisLayout.props.backgroundPos.y, 0.0);
+ wPrefGetFloat("layout", "BackgroundAngle", &thisLayout.props.backgroundAngle, 0.0);
+ long screen_long;
+ wPrefGetInteger("layout", "BackgroundScreen", &screen_long, 0L);
+ thisLayout.props.backgroundScreen = screen_long;
+ wPrefGetFloat("layout", "BackgroundSize", &thisLayout.props.backgroundSize, 0.0);
+}
+
+static wBool_t inited;
+
+/**************************************************************************************
+ * Either Clear Background Parms or (if the first time called) Load from Saved Parms
+ **************************************************************************************/
+void
+LayoutBackGroundInit(BOOL_T clear) {
+ if (clear) {
+ SetLayoutBackGroundFullPath(noname);
+ SetLayoutBackGroundPos(zero);
+ SetLayoutBackGroundAngle(0.0);
+ SetLayoutBackGroundScreen(0);
+ SetLayoutBackGroundSize(0.0);
+ LayoutBackGroundSave();
+ } else { //First Time and not "Clear"
+ inited = TRUE;
+ LayoutBackGroundLoad();
+ }
+ char * str = GetLayoutBackGroundFullPath();
+ if (str && str[0]) {
+ if (!LoadBackGroundImage()) { //Failed -> Wipe Out
+ SetLayoutBackGroundFullPath(noname);
+ SetLayoutBackGroundPos(zero);
+ SetLayoutBackGroundAngle(0.0);
+ SetLayoutBackGroundScreen(0);
+ SetLayoutBackGroundSize(0.0);
+ LayoutBackGroundSave();
+ }
+ } else {
+ wDrawSetBackground( mainD.d, NULL, NULL);
+ }
+
}