add rear differential type to setup menu

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@6921 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: 527781de325a34857da5fcb6f4924594fbd2999a
Former-commit-id: 0932acbc768c704f974519dc9e5019bf89fdcaee
This commit is contained in:
iobyte 2020-04-15 00:56:03 +00:00
parent c084b7fdd4
commit 0f2149bba5
4 changed files with 430 additions and 107 deletions

View file

@ -593,7 +593,7 @@ createParmHeader (const char *file)
}
static void
addWithin (struct param *curParam, char *s1)
addWithin (struct param *curParam, const char *s1)
{
struct within *curWithin;
@ -2440,6 +2440,37 @@ GfParmExistsSection (void *handle, const char *path)
return section != 0 ? 1 : 0;
}
/** Check if a parameter exists.
@ingroup paramsdata
@param handle handle of parameters
@param path path of param
@param key key name
@return 1 exists
0 doesn't exist
*/
int
GfParmExistsParam(void *handle, const char *path, const char *key)
{
struct parmHandle *parmHandle = (struct parmHandle *)handle;
struct parmHeader *conf;
struct param *param;
if ((parmHandle == NULL) || (parmHandle->magic != PARM_MAGIC)) {
GfLogError ("GfParmSetNum: bad handle (%p)\n", parmHandle);
return 0;
}
conf = parmHandle->conf;
param = getParamByName (conf, path, key, 0);
if (!param)
{
return 0;
}
return 1;
}
/** Seek the first sub-section element of a section.
@ingroup paramslist
@param handle handle of parameters
@ -2814,6 +2845,47 @@ GfParmGetStr (void *parmHandle, const char *path, const char *key, const char *d
return val;
}
/** Get string parameter in values.
@ingroup paramsdata
@param parmHandle Configuration handle
@param path Parameter section name
@param key Parameter name
@return vector of possible strings
*/
std::vector<std::string>
GfParmGetStrIn(void *parmHandle, const char *path, const char *key)
{
struct param *param;
struct parmHandle *handle = (struct parmHandle *)parmHandle;
struct parmHeader *conf;
struct within *curWithin;
std::vector<std::string> paramsInList;
if ((handle == NULL) || (handle->magic != PARM_MAGIC)) {
GfLogError ("GfParmListGetStrInList: bad handle (%p)\n", parmHandle);
return paramsInList;
}
conf = handle->conf;
param = getParamByName (conf, path, key, 0);
if (!param || !(param->value) || !strlen (param->value) || (param->type != P_STR && param->type != P_FORM)) {
return paramsInList;
}
curWithin = GF_TAILQ_FIRST (&(param->withinList));
if (curWithin)
{
paramsInList.push_back(curWithin->val);
while ((curWithin = GF_TAILQ_NEXT (curWithin, linkWithin)) != NULL)
{
paramsInList.push_back(curWithin->val);
}
}
return paramsInList;
}
/** Get string parameter value.
@ingroup paramsdata
@param parmHandle Configuration handle
@ -3430,8 +3502,6 @@ GfParmGetCurFormula (void *handle, char const *path, char const *key)
return param->value;
}
/** Set a string parameter in a config file.
@ingroup paramsdata
@param handle handle of parameters
@ -3447,37 +3517,135 @@ GfParmSetStr(void *handle, const char *path, const char *key, const char *val)
{
struct parmHandle *parmHandle = (struct parmHandle *)handle;
struct parmHeader *conf;
struct param *param;
struct param *param;
if ((parmHandle == NULL) || (parmHandle->magic != PARM_MAGIC)) {
GfLogError ("GfParmSetStr: bad handle (%p)\n", parmHandle);
return -1;
}
if ((parmHandle == NULL) || (parmHandle->magic != PARM_MAGIC)) {
GfLogError ("GfParmSetStr: bad handle (%p)\n", parmHandle);
return -1;
}
conf = parmHandle->conf;
conf = parmHandle->conf;
if (!val || !strlen (val)) {
/* Remove the entry */
removeParamByName (conf, path, key);
return 0;
if (!val || !strlen (val)) {
/* Remove the entry */
removeParamByName (conf, path, key);
return 0;
}
param = getParamByName (conf, path, key, PARAM_CREATE);
if (!param) {
return -1;
return -1;
}
param->type = P_STR;
freez (param->value);
param->value = strdup (val);
if (!param->value) {
GfLogError ("gfParmSetStr: strdup (%s) failed\n", val);
removeParamByName (conf, path, key);
return -1;
GfLogError ("gfParmSetStr: strdup (%s) failed\n", val);
removeParamByName (conf, path, key);
return -1;
}
return 0;
}
/** Set a string parameter in vector in a config file.
@ingroup paramsdata
@param handle handle of parameters
@param path path of param
@param key key name
@param in vector of possible values
@return 0 ok
<br>-1 error
@warning The key is created is necessary
*/
int
GfParmSetStrIn(void *handle, const char *path, const char *key, const std::vector<std::string> &in)
{
struct parmHandle *parmHandle = (struct parmHandle *)handle;
struct parmHeader *conf;
struct param *param;
if ((parmHandle == NULL) || (parmHandle->magic != PARM_MAGIC)) {
GfLogError ("GfParmSetStrIn: bad handle (%p)\n", parmHandle);
return -1;
}
conf = parmHandle->conf;
param = getParamByName (conf, path, key, PARAM_CREATE);
if (!param) {
return -1;
}
param->type = P_STR;
struct within *within;
while ((within = GF_TAILQ_FIRST (&param->withinList)) != GF_TAILQ_END (&param->withinList)) {
GF_TAILQ_REMOVE (&param->withinList, within, linkWithin);
freez(within->val);
free(within);
}
for (size_t i = 0; i < in.size(); ++i)
addWithin(param, in[i].c_str());
return 0;
}
/** Set a string parameter in a config file.
@ingroup paramsdata
@param handle handle of parameters
@param path path of param
@param key key name
@param val value (NULL or empty string to remove the parameter)
@param in vector of possible values
@return 0 ok
<br>-1 error
@warning The key is created is necessary
*/
int GfParmSetStrAndIn(void *handle, const char *path, const char *key, const char *val, const std::vector<std::string> &in)
{
struct parmHandle *parmHandle = (struct parmHandle *)handle;
struct parmHeader *conf;
struct param *param;
if ((parmHandle == NULL) || (parmHandle->magic != PARM_MAGIC)) {
GfLogError ("GfParmSetStrAndIn: bad handle (%p)\n", parmHandle);
return -1;
}
conf = parmHandle->conf;
if (!val || !strlen (val)) {
/* Remove the entry */
removeParamByName (conf, path, key);
return 0;
}
param = getParamByName (conf, path, key, PARAM_CREATE);
if (!param) {
return -1;
}
param->type = P_STR;
freez (param->value);
param->value = strdup (val);
if (!param->value) {
GfLogError ("gfParmSetStrAndIn: strdup (%s) failed\n", val);
removeParamByName (conf, path, key);
return -1;
}
struct within *within;
while ((within = GF_TAILQ_FIRST (&param->withinList)) != GF_TAILQ_END (&param->withinList)) {
GF_TAILQ_REMOVE (&param->withinList, within, linkWithin);
freez(within->val);
free(within);
}
for (size_t i = 0; i < in.size(); ++i)
addWithin(param, in[i].c_str());
return 0;
}
/** Set a string parameter in a config file.
@ingroup paramslist
@param handle handle of parameters

View file

@ -429,11 +429,14 @@ TGF_API void GfParmSetDTD (void *parmHandle, char *dtd, char*header);
/* get string parameter value */
TGF_API const char *GfParmGetStr(void *handle, const char *path, const char *key, const char *deflt);
TGF_API char *GfParmGetStrNC(void *handle, const char *path, const char *key, char *deflt);
TGF_API std::vector<std::string> GfParmGetStrIn(void *handle, const char *path, const char *key);
/* get string parameter value */
TGF_API const char *GfParmGetCurStr(void *handle, const char *path, const char *key, const char *deflt);
TGF_API char *GfParmGetCurStrNC(void *handle, const char *path, const char *key, char *deflt);
/* set string parameter value */
TGF_API int GfParmSetStr(void *handle, const char *path, const char *key, const char *val);
TGF_API int GfParmSetStrIn(void *handle, const char *path, const char *key, const std::vector<std::string> &in);
TGF_API int GfParmSetStrAndIn(void *handle, const char *path, const char *key, const char *val, const std::vector<std::string> &in);
/* set string parameter value */
TGF_API int GfParmSetCurStr(void *handle, const char *path, const char *key, const char *val);
@ -491,6 +494,7 @@ TGF_API void GfParmRemove(void *handle, const char *path, const char *key);
TGF_API int GfParmRemoveSection (void *handle, const char *path);
TGF_API int GfParmExistsSection(void *handle, const char *path);
TGF_API std::vector<std::string> GfParmListGetSectionNamesList(void *handle);
TGF_API int GfParmExistsParam(void *handle, const char *path, const char *key);
TGF_API int GfParmGetEltNb(void *handle, const char *path);
TGF_API int GfParmListSeekFirst(void *handle, const char *path);
TGF_API int GfParmListSeekNext(void *handle, const char *path);

View file

@ -84,6 +84,14 @@ void CarSetupMenu::onPreviousCallback(void *pMenu)
pCarSetupMenu->onPrevious();
}
void CarSetupMenu::onComboCallback(tComboBoxInfo *pInfo)
{
// Get the CarSetupMenu instance from call-back user data.
CarSetupMenu *pCarSetupMenu = static_cast<CarSetupMenu::ComboCallbackData *>(pInfo->userData)->menu;
pCarSetupMenu->onCombo(pInfo);
}
// member functions
void CarSetupMenu::onActivate()
@ -95,6 +103,13 @@ void CarSetupMenu::onActivate()
// Initialize GUI from loaded values.
updateControls();
// Initialize combo callback user data.
for (size_t i = 0; i < ITEMS_PER_PAGE; ++i)
{
comboCallbackData[i].menu = this;
comboCallbackData[i].index = i;
}
}
void CarSetupMenu::onAccept()
@ -120,9 +135,16 @@ void CarSetupMenu::onReset()
// Reset all values on current page to their defaults.
for (size_t index = 0; index < ITEMS_PER_PAGE; index++)
{
attnum &att = items[currentPage][index];
att.value = att.defaultValue;
}
attribute &att = items[currentPage][index];
if (att.type == "edit")
{
att.value = att.defaultValue;
}
else if (att.type == "combo")
{
att.strValue = att.defaultStrValue;
}
}
// Update the GUI.
updateControls();
@ -160,12 +182,22 @@ void CarSetupMenu::onNext()
updateControls();
}
void CarSetupMenu::onCombo(tComboBoxInfo *pInfo)
{
ComboCallbackData *pData = static_cast<CarSetupMenu::ComboCallbackData *>(pInfo->userData);
// Use currentPage and index in callback data to find item.
attribute &att = items[currentPage][pData->index];
att.strValue = pInfo->vecChoices[pInfo->nPos];
}
void CarSetupMenu::readCurrentPage()
{
for (size_t index = 0; index < ITEMS_PER_PAGE; index++)
{
attnum &att = items[currentPage][index];
if (att.exists)
attribute &att = items[currentPage][index];
if (att.exists && att.type == "edit")
{
std::string strValue(GfuiEditboxGetString(getMenuHandle(), att.editId));
std::istringstream issValue(strValue);
@ -181,7 +213,7 @@ void CarSetupMenu::updateControls()
for (size_t index = 0; index < ITEMS_PER_PAGE; ++index)
{
attnum &att = items[currentPage][index];
attribute &att = items[currentPage][index];
// Set label text.
std::ostringstream ossLabel;
@ -203,53 +235,88 @@ void CarSetupMenu::updateControls()
// Set default label text.
if (att.exists)
{
// Check for missing min and max.
if (att.minValue == att.maxValue)
if (att.type == "edit")
{
ossLabel << std::fixed << std::setprecision(att.precision)
<< "Default: " << att.defaultValue;
// Check for missing min and max.
if (att.minValue == att.maxValue)
{
ossLabel << std::fixed << std::setprecision(att.precision)
<< "Default: " << att.defaultValue;
}
else
{
ossLabel << std::fixed << std::setprecision(att.precision)
<< "Min: " << att.minValue
<< " Default: " << att.defaultValue
<< " Max: " << att.maxValue;
}
}
else
else if (att.type == "combo")
{
ossLabel << std::fixed << std::setprecision(att.precision)
<< "Min: " << att.minValue
<< " Default: " << att.defaultValue
<< " Max: " << att.maxValue;
ossLabel << "Default: " << att.defaultStrValue;
}
}
GfuiLabelSetText(getMenuHandle(),
att.defaultLabelId,
ossLabel.str().c_str());
}
// Update the edit boxes.
for (size_t index = 0; index < ITEMS_PER_PAGE; ++index)
{
attnum &att = items[currentPage][index];
// Update the edit or combo boxes.
if (att.label.empty())
{
GfuiVisibilitySet(getMenuHandle(), att.editId, GFUI_INVISIBLE);
GfuiVisibilitySet(getMenuHandle(), att.comboId, GFUI_INVISIBLE);
}
else
{
GfuiVisibilitySet(getMenuHandle(), att.editId, GFUI_VISIBLE);
if (att.exists)
if (att.type == "edit")
{
std::ostringstream ossValue;
ossValue << std::fixed << std::setprecision(att.precision) << att.value;
GfuiEditboxSetString(getMenuHandle(), att.editId, ossValue.str().c_str());
if (att.minValue == att.maxValue)
GfuiEnable(getMenuHandle(), att.editId, GFUI_DISABLE);
else
GfuiEnable(getMenuHandle(), att.editId, GFUI_ENABLE);
GfuiVisibilitySet(getMenuHandle(), att.editId, GFUI_VISIBLE);
GfuiVisibilitySet(getMenuHandle(), att.comboId, GFUI_INVISIBLE);
}
else if (att.type == "combo")
{
GfuiVisibilitySet(getMenuHandle(), att.editId, GFUI_INVISIBLE);
GfuiVisibilitySet(getMenuHandle(), att.comboId, GFUI_VISIBLE);
}
else
{
GfuiEditboxSetString(getMenuHandle(), att.editId, "----");
GfuiEnable(getMenuHandle(), att.editId, GFUI_DISABLE);
GfuiVisibilitySet(getMenuHandle(), att.editId, GFUI_INVISIBLE);
GfuiVisibilitySet(getMenuHandle(), att.comboId, GFUI_INVISIBLE);
}
if (att.exists)
{
if (att.type == "edit")
{
std::ostringstream ossValue;
ossValue << std::fixed << std::setprecision(att.precision) << att.value;
GfuiEditboxSetString(getMenuHandle(), att.editId, ossValue.str().c_str());
if (att.minValue == att.maxValue)
GfuiEnable(getMenuHandle(), att.editId, GFUI_DISABLE);
else
GfuiEnable(getMenuHandle(), att.editId, GFUI_ENABLE);
}
else if (att.type == "combo")
{
GfuiComboboxClear(getMenuHandle(), att.comboId);
size_t index = 0;
for (size_t i = 0; i < att.in.size(); ++i)
{
GfuiComboboxAddText(getMenuHandle(), att.comboId, att.in[i].c_str());
if (att.in[i] == att.strValue)
index = i;
}
GfuiComboboxSetSelectedIndex(getMenuHandle(), att.comboId, index);
}
}
else
{
if (att.type == "edit")
{
GfuiEditboxSetString(getMenuHandle(), att.editId, "----");
GfuiEnable(getMenuHandle(), att.editId, GFUI_DISABLE);
}
}
}
}
@ -321,34 +388,61 @@ void CarSetupMenu::loadSettings()
continue;
}
attnum &att = items[page][index];
attribute &att = items[page][index];
std::string strIndex(std::to_string(static_cast<unsigned long long>(index)));
att.labelId = getDynamicControlId(std::string("Label" + std::to_string(static_cast<unsigned long long>(index))).c_str());
att.editId = getDynamicControlId(std::string("Edit" + std::to_string(static_cast<unsigned long long>(index))).c_str());
att.defaultLabelId = getDynamicControlId(std::string("DefaultLabel" + std::to_string(static_cast<unsigned long long>(index))).c_str());
att.labelId = getDynamicControlId(std::string("Label" + strIndex).c_str());
att.editId = getDynamicControlId(std::string("Edit" + strIndex).c_str());
att.comboId = getDynamicControlId(std::string("Combo" + strIndex).c_str());
att.defaultLabelId = getDynamicControlId(std::string("DefaultLabel" + strIndex).c_str());
att.type = GfParmGetStr(hparmItems, strSection.c_str(), "type", "");
att.section = GfParmGetStr(hparmItems, strSection.c_str(), "section", "");
att.param = GfParmGetStr(hparmItems, strSection.c_str(), "param", "");
att.units = GfParmGetStr(hparmItems, strSection.c_str(), "unit", "");
att.label = GfParmGetStr(hparmItems, strSection.c_str(), "label", "");
att.precision = GfParmGetNum(hparmItems, strSection.c_str(), "precision", "", 0);
// Read values from car.
att.exists = GfParmGetNumWithLimits(hparmCar, att.section.c_str(), att.param.c_str(), att.units.c_str(),
&att.defaultValue, &att.minValue, &att.maxValue) == 0;
if (att.type == "edit")
{
att.units = GfParmGetStr(hparmItems, strSection.c_str(), "unit", "");
att.precision = GfParmGetNum(hparmItems, strSection.c_str(), "precision", "", 0);
// Read value from car setup if avaliable.
if (hparmCarSetup)
att.value = GfParmGetNum(hparmCarSetup, att.section.c_str(), att.param.c_str(),
att.units.c_str(), att.defaultValue);
else
att.value = att.defaultValue;
// Read values from car.
att.exists = GfParmGetNumWithLimits(hparmCar, att.section.c_str(), att.param.c_str(), att.units.c_str(),
&att.defaultValue, &att.minValue, &att.maxValue) == 0;
GfLogDebug("section: \"%s\" param: \"%s\" units: \"%s\" label: \"%s\" page: %zu "
"index: %zu precision: %d labelIs: %d editId: %d defaultLabelId: %d "
"exists: %d min: %f default %f max: %f value: %f\n",
att.section.c_str(), att.param.c_str(), att.units.c_str(), att.label.c_str(),
page, index, att.precision, att.labelId, att.editId, att.defaultLabelId,
att.exists, att.minValue, att.defaultValue, att.maxValue, att.value);
// Read value from car setup if avaliable.
if (hparmCarSetup)
att.value = GfParmGetNum(hparmCarSetup, att.section.c_str(), att.param.c_str(),
att.units.c_str(), att.defaultValue);
else
att.value = att.defaultValue;
GfLogDebug("section: \"%s\" param: \"%s\" units: \"%s\" label: \"%s\" page: %zu "
"index: %zu precision: %d labelId: %d editId: %d defaultLabelId: %d "
"exists: %d min: %f default %f max: %f value: %f\n",
att.section.c_str(), att.param.c_str(), att.units.c_str(),
att.label.c_str(), page, index, att.precision, att.labelId, att.editId,
att.defaultLabelId, att.exists, att.minValue, att.defaultValue, att.maxValue, att.value);
}
else if (att.type == "combo")
{
att.defaultStrValue = GfParmGetStr(hparmCar, att.section.c_str(), att.param.c_str(), "");
att.exists = !att.defaultStrValue.empty();
att.in = GfParmGetStrIn(hparmCar, att.section.c_str(), att.param.c_str());
if (hparmCarSetup)
att.strValue = GfParmGetStr(hparmCarSetup, att.section.c_str(), att.param.c_str(),
att.defaultStrValue.c_str());
else
att.strValue = att.defaultStrValue;
GfLogDebug("section: \"%s\" param: \"%s\" label: \"%s\" page: %zu "
"index: %zu labelId: %d comboId: %d defaultLabelId: %d "
"exists: %d, in: %zu default: \"%s\" value: \"%s\"\n",
att.section.c_str(), att.param.c_str(), att.label.c_str(),
page, index, att.labelId, att.comboId, att.defaultLabelId,
att.exists, att.in.size(), att.defaultStrValue.c_str(),
att.strValue.c_str());
}
}
// Save the control id for all items.
@ -356,14 +450,17 @@ void CarSetupMenu::loadSettings()
{
for (size_t index = 0; index < ITEMS_PER_PAGE; ++index)
{
attnum &att = items[page][index];
attribute &att = items[page][index];
std::string strIndex(std::to_string(static_cast<unsigned long long>(index)));
if (!att.labelId)
att.labelId = getDynamicControlId(std::string("Label" + std::to_string(static_cast<unsigned long long>(index))).c_str());
att.labelId = getDynamicControlId(std::string("Label" + strIndex).c_str());
if (!att.editId)
att.editId = getDynamicControlId(std::string("Edit" + std::to_string(static_cast<unsigned long long>(index))).c_str());
att.editId = getDynamicControlId(std::string("Edit" + strIndex).c_str());
if (!att.comboId)
att.comboId = getDynamicControlId(std::string("Combo" + strIndex).c_str());
if (!att.defaultLabelId)
att.defaultLabelId = getDynamicControlId(std::string("DefaultLabel" + std::to_string(static_cast<unsigned long long>(index))).c_str());
att.defaultLabelId = getDynamicControlId(std::string("DefaultLabel" + strIndex).c_str());
}
}
}
@ -414,12 +511,50 @@ void CarSetupMenu::storeSettings()
{
for (size_t index = 0; index < ITEMS_PER_PAGE; ++index)
{
attnum &att = items[page][index];
attribute &att = items[page][index];
// Only write items that exist and have been changed.
if (att.exists && (att.value != att.defaultValue))
if (att.exists)
{
GfParmSetNum(hparmCarSetup, att.section.c_str(), att.param.c_str(), att.units.c_str(),
att.value, att.minValue, att.maxValue);
if (att.type == "edit")
{
if (att.value != att.defaultValue)
{
GfParmSetNum(hparmCarSetup, att.section.c_str(), att.param.c_str(),
att.units.c_str(), att.value, att.minValue, att.maxValue);
}
else
{
// Remove it if it is the same as default.
if (GfParmExistsParam(hparmCarSetup, att.section.c_str(), att.param.c_str()))
{
// FIXME This crashes when the last section is deleted so set
// the parameter to its default value.
//GfParmRemove(hparmCarSetup, att.section.c_str(), att.param.c_str());
GfParmSetNum(hparmCarSetup, att.section.c_str(), att.param.c_str(),
att.units.c_str(), att.value, att.minValue, att.maxValue);
}
}
}
else if (att.type == "combo")
{
if (att.strValue != att.defaultStrValue)
{
GfParmSetStrAndIn(hparmCarSetup, att.section.c_str(), att.param.c_str(),
att.strValue.c_str(), att.in);
}
else
{
// Remove it if it is the same as default.
if (GfParmExistsParam(hparmCarSetup, att.section.c_str(), att.param.c_str()))
{
// FIXME This crashes when the last section is deleted so set
// the parameter to its default value.
//GfParmRemove(hparmCarSetup, att.section.c_str(), att.param.c_str());
GfParmSetStrAndIn(hparmCarSetup, att.section.c_str(), att.param.c_str(),
att.strValue.c_str(), att.in);
}
}
}
}
}
}
@ -456,9 +591,11 @@ bool CarSetupMenu::initialize(void *pMenu, const GfRace *pRace, const GfDriver *
// Create items.
for (size_t index = 0; index < ITEMS_PER_PAGE; ++index)
{
createLabelControl(std::string("Label" + std::to_string(static_cast<unsigned long long>(index))).c_str());
createEditControl(std::string("Edit" + std::to_string(static_cast<unsigned long long>(index))).c_str(), this, NULL, NULL);
createLabelControl(std::string("DefaultLabel" + std::to_string(static_cast<unsigned long long>(index))).c_str());
std::string strIndex(std::to_string(static_cast<unsigned long long>(index)));
createLabelControl(std::string("Label" + strIndex).c_str());
createEditControl(std::string("Edit" + strIndex).c_str(), this, NULL, NULL);
createComboboxControl(std::string("Combo" + strIndex).c_str(), &comboCallbackData[index], onComboCallback);
createLabelControl(std::string("DefaultLabel" + strIndex).c_str());
}
// Create buttons.

View file

@ -41,6 +41,40 @@ public:
const GfRace *pRace,
const GfDriver *pDriver);
struct attribute
{
int labelId;
int editId;
int comboId;
int defaultLabelId;
bool exists;
tdble value;
tdble minValue;
tdble defaultValue;
tdble maxValue;
std::string type;
std::string section;
std::string param;
std::string units;
std::string label;
std::string strValue;
std::string defaultStrValue;
std::vector<std::string> in;
int precision;
attribute() :
labelId(0), editId(0), comboId(0), defaultLabelId(0), exists(false),
value(0), minValue(0), defaultValue(0), maxValue(0), precision(0)
{
}
};
struct ComboCallbackData
{
CarSetupMenu *menu;
size_t index;
};
// callback functions must be static
static void onActivateCallback(void *pMenu);
static void onAcceptCallback(void *pMenu);
@ -48,29 +82,7 @@ public:
static void onResetCallback(void *pMenu);
static void onPreviousCallback(void *pMenu);
static void onNextCallback(void *pMenu);
struct attnum
{
int labelId;
int editId;
int defaultLabelId;
bool exists;
tdble value;
tdble minValue;
tdble defaultValue;
tdble maxValue;
std::string section;
std::string param;
std::string units;
std::string label;
int precision;
attnum() :
labelId(0), editId(0), defaultLabelId(0), exists(false),
value(0), minValue(0), defaultValue(0), maxValue(0), precision(0)
{
}
};
static void onComboCallback(tComboBoxInfo *pInfo);
private:
@ -88,6 +100,7 @@ private:
void onReset();
void onPrevious();
void onNext();
void onCombo(tComboBoxInfo *pInfo);
// The target race.
const GfRace *_pRace;
@ -95,8 +108,9 @@ private:
// The target driver.
const GfDriver *_pDriver;
std::vector<std::array<attnum, ITEMS_PER_PAGE> > items;
std::vector<std::array<attribute, ITEMS_PER_PAGE> > items;
size_t currentPage;
ComboCallbackData comboCallbackData[ITEMS_PER_PAGE];
};
#endif /* _CARSETUPMENU_H_ */