add multiple setup page support and moved item configuration to xml file

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

Former-commit-id: f8bf263c254cd44c11e23f1f270ddc8a7ba785a9
Former-commit-id: 067ca520523b190a6d7cc9212acd0e68edabb7f3
This commit is contained in:
iobyte 2020-04-09 22:37:34 +00:00
parent b5a6ce554d
commit 9f997d2ac7
4 changed files with 263 additions and 180 deletions

View file

@ -2736,6 +2736,37 @@ GfParmListGetParamsNamesList (void *handle, const char *path)
return paramsNamesList; return paramsNamesList;
} }
/** Get the names of the sections
@ingroup paramslist
@param handle handle of parameters
@param path path of list
@return a vector of strings containing the names of the sections in the list
*/
std::vector<std::string>
GfParmListGetSectionNamesList(void *handle)
{
struct parmHandle *parmHandle = (struct parmHandle *)handle;
struct parmHeader *conf;
struct section *section;
std::vector<std::string> sectionNamesList;
if ((parmHandle == NULL) || (parmHandle->magic != PARM_MAGIC)) {
GfLogError ("GfParmListGetSectionNamesList: bad handle (%p)\n", parmHandle);
return sectionNamesList;
}
conf = parmHandle->conf;
section = GF_TAILQ_FIRST (&(conf->rootSection->subSectionList));
while (section)
{
sectionNamesList.push_back(section->fullName);
section = GF_TAILQ_NEXT (section, linkSection);
}
return sectionNamesList;
}
/** Get string parameter value. /** Get string parameter value.
@ingroup paramsdata @ingroup paramsdata
@param parmHandle Configuration handle @param parmHandle Configuration handle

View file

@ -490,6 +490,7 @@ TGF_API int GfParmGetNumBoundaries(void *handle, char *path, char *key, tdble *m
TGF_API void GfParmRemove(void *handle, const char *path, const char *key); TGF_API void GfParmRemove(void *handle, const char *path, const char *key);
TGF_API int GfParmRemoveSection (void *handle, const char *path); TGF_API int GfParmRemoveSection (void *handle, const char *path);
TGF_API int GfParmExistsSection(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 GfParmGetEltNb(void *handle, const char *path); TGF_API int GfParmGetEltNb(void *handle, const char *path);
TGF_API int GfParmListSeekFirst(void *handle, const char *path); TGF_API int GfParmListSeekFirst(void *handle, const char *path);
TGF_API int GfParmListSeekNext(void *handle, const char *path); TGF_API int GfParmListSeekNext(void *handle, const char *path);

View file

@ -52,8 +52,13 @@ void CarSetupMenu::onAccept(void *pMenu)
{ {
CarSetupMenu *pCarSetupMenu = static_cast<CarSetupMenu*>(pMenu); CarSetupMenu *pCarSetupMenu = static_cast<CarSetupMenu*>(pMenu);
// Get the current page values.
pCarSetupMenu->readCurrentPage();
// Save all page values.
pCarSetupMenu->storeSettings(); pCarSetupMenu->storeSettings();
// Switch back to garage menu.
GfuiScreenActivate(pCarSetupMenu->getPreviousMenuHandle()); GfuiScreenActivate(pCarSetupMenu->getPreviousMenuHandle());
} }
@ -71,111 +76,140 @@ void CarSetupMenu::onReset(void *pMenu)
// Get the CarSetupMenu instance from call-back user data. // Get the CarSetupMenu instance from call-back user data.
CarSetupMenu *pCarSetupMenu = static_cast<CarSetupMenu*>(pMenu); CarSetupMenu *pCarSetupMenu = static_cast<CarSetupMenu*>(pMenu);
pCarSetupMenu->brakeRepartition.value = pCarSetupMenu->brakeRepartition.defaultValue; // Reset all values on current page to their defaults.
pCarSetupMenu->frontARB.value = pCarSetupMenu->frontARB.defaultValue; for (size_t index = 0; index < ITEMS_PER_PAGE; index++)
pCarSetupMenu->rearARB.value = pCarSetupMenu->rearARB.defaultValue; {
pCarSetupMenu->frontWing.value = pCarSetupMenu->frontWing.defaultValue; attnum &att = pCarSetupMenu->items[pCarSetupMenu->currentPage][index];
pCarSetupMenu->rearWing.value = pCarSetupMenu->rearWing.defaultValue; att.value = att.defaultValue;
pCarSetupMenu->rearDiffSlip.value = pCarSetupMenu->rearDiffSlip.defaultValue; }
pCarSetupMenu->rearDiffCoastSlip.value = pCarSetupMenu->rearDiffCoastSlip.defaultValue;
pCarSetupMenu->rearDiffRatio.value = pCarSetupMenu->rearDiffRatio.defaultValue;
// Update the GUI.
pCarSetupMenu->updateControls(); pCarSetupMenu->updateControls();
} }
void CarSetupMenu::updateControl(const attnum &att) void CarSetupMenu::readCurrentPage()
{ {
if (att.exists) for (size_t index = 0; index < ITEMS_PER_PAGE; index++)
{ {
std::ostringstream ossValue; attnum &att = items[currentPage][index];
ossValue << std::fixed << std::setprecision(att.precision) << att.value; if (att.exists)
GfuiEditboxSetString(getMenuHandle(), att.editId, ossValue.str().c_str()); {
std::string strValue(GfuiEditboxGetString(getMenuHandle(), att.editId));
std::istringstream issValue(strValue);
issValue >> att.value;
}
}
}
if (att.minValue == att.maxValue) void CarSetupMenu::onPrevious(void *pMenu)
GfuiEnable(getMenuHandle(), att.editId, GFUI_DISABLE); {
else // Get the CarSetupMenu instance from call-back user data.
GfuiEnable(getMenuHandle(), att.editId, GFUI_ENABLE); CarSetupMenu *pCarSetupMenu = static_cast<CarSetupMenu*>(pMenu);
}
else // Get the current page values.
{ pCarSetupMenu->readCurrentPage();
GfuiEditboxSetString(getMenuHandle(), att.editId, "----");
GfuiEnable(getMenuHandle(), att.editId, GFUI_DISABLE); // Switch to previous page.
} pCarSetupMenu->currentPage--;
// Update the GUI.
pCarSetupMenu->updateControls();
}
void CarSetupMenu::onNext(void *pMenu)
{
// Get the CarSetupMenu instance from call-back user data.
CarSetupMenu *pCarSetupMenu = static_cast<CarSetupMenu*>(pMenu);
// Get the current page values.
pCarSetupMenu->readCurrentPage();
// Switch to next page.
pCarSetupMenu->currentPage++;
// update the GUI.
pCarSetupMenu->updateControls();
} }
void CarSetupMenu::updateControls() void CarSetupMenu::updateControls()
{ {
updateControl(brakeRepartition); GfuiEnable(getMenuHandle(), getDynamicControlId("PreviousButton"), currentPage != 0 ? GFUI_ENABLE : GFUI_DISABLE);
updateControl(frontARB); GfuiEnable(getMenuHandle(), getDynamicControlId("NextButton"), currentPage < (items.size() - 1) ? GFUI_ENABLE : GFUI_DISABLE);
updateControl(rearARB);
updateControl(frontWing);
updateControl(rearWing);
updateControl(rearDiffSlip);
updateControl(rearDiffCoastSlip);
updateControl(rearDiffRatio);
}
void CarSetupMenu::loadSetting(const char *label, const char *edit, const char *defaultLabel, for (size_t index = 0; index < ITEMS_PER_PAGE; ++index)
void *hparmCar, void *hparmCarSetup, attnum &att,
const char *section, const char *param, const char *labelStr,
const char *units, int precision)
{
att.labelId = getDynamicControlId(label);
att.editId = getDynamicControlId(edit);
att.defaultLabelId = getDynamicControlId(defaultLabel);
att.section = section;
att.param = param;
att.units = units;
att.precision = precision;
// Set label text.
std::ostringstream ossLabel;
ossLabel << labelStr;
if (!att.units.empty())
ossLabel << " (" << att.units << ")";
ossLabel << ":";
GfuiLabelSetText(getMenuHandle(),
att.labelId,
ossLabel.str().c_str());
// 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;
ossLabel.str("");
ossLabel.clear();
// Set default label text.
if (att.exists)
{ {
// Check for missing min and max. attnum &att = items[currentPage][index];
if (att.minValue == att.maxValue)
// Set label text.
std::ostringstream ossLabel;
if (!att.label.empty())
{ {
ossLabel << std::fixed << std::setprecision(att.precision) ossLabel << att.label;
<< "Default: " << att.defaultValue; if (!att.units.empty())
ossLabel << " (" << att.units << ")";
ossLabel << ":";
}
GfuiLabelSetText(getMenuHandle(),
att.labelId,
ossLabel.str().c_str());
ossLabel.str("");
ossLabel.clear();
// Set default label text.
if (att.exists)
{
// 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;
}
}
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];
if (att.label.empty())
{
GfuiVisibilitySet(getMenuHandle(), att.editId, GFUI_INVISIBLE);
} }
else else
{ {
ossLabel << std::fixed << std::setprecision(att.precision) GfuiVisibilitySet(getMenuHandle(), att.editId, GFUI_VISIBLE);
<< "Min: " << att.minValue
<< " Default: " << att.defaultValue if (att.exists)
<< " Max: " << att.maxValue; {
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
{
GfuiEditboxSetString(getMenuHandle(), att.editId, "----");
GfuiEnable(getMenuHandle(), att.editId, GFUI_DISABLE);
}
} }
} }
GfuiLabelSetText(getMenuHandle(),
att.defaultLabelId,
ossLabel.str().c_str());
// 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 value: %f min: %f default: %f max: %f\n",
att.section.c_str(), att.param.c_str(), att.value, att.minValue,
att.defaultValue, att.maxValue);
} }
void CarSetupMenu::loadSettings() void CarSetupMenu::loadSettings()
@ -206,37 +240,90 @@ void CarSetupMenu::loadSettings()
void *hparmCarSetup = GfParmReadFile(ossCarSetupFileName.str().c_str(), GFPARM_RMODE_STD); void *hparmCarSetup = GfParmReadFile(ossCarSetupFileName.str().c_str(), GFPARM_RMODE_STD);
if (!hparmCarSetup) if (!hparmCarSetup)
{ {
GfLogError("Car Setup %s/%s (file %s not %s)\n", GfLogInfo("Car Setup: %s/%s (file %s not %s)\n",
getCar()->getName().c_str(), getTrack()->getName().c_str(), ossCarSetupFileName.str().c_str(), getCar()->getName().c_str(), getTrack()->getName().c_str(), ossCarSetupFileName.str().c_str(),
GfFileExists(ossCarSetupFileName.str().c_str()) ? "readable" : "found"); GfFileExists(ossCarSetupFileName.str().c_str()) ? "readable" : "found");
} }
else else
GfLogInfo("Opened car setup file: %s\n", ossCarSetupFileName.str().c_str()); GfLogInfo("Opened car setup file: %s\n", ossCarSetupFileName.str().c_str());
loadSetting("BrakeBiasLabel", "BrakeBiasEdit", "BrakeBiasDefaultLabel", void *hparmItems = GfuiMenuLoad("carsetupmenuitems.xml");
hparmCar, hparmCarSetup, brakeRepartition, SECT_BRKSYST, PRM_BRKREP, if (!hparmItems)
"Brake Bias", "%", 1); {
loadSetting("FrontARBLabel", "FrontARBEdit", "FrontARBDefaultLabel", GfLogError("Car Setup Items (file %s not %s)\n",
hparmCar, hparmCarSetup, frontARB, SECT_FRNTARB, PRM_SPR, "carsetupmenuitems.xml",
"Front Anti-Roll Bar", "kN/m", 1); GfFileExists("carsetupmenuitems.xml") ? "readable" : "found");
loadSetting("RearARBLabel", "RearARBEdit", "RearARBDefaultLabel", }
hparmCar, hparmCarSetup, rearARB, SECT_REARARB, PRM_SPR, else
"Rear Anti-Roll Bar", "kN/m", 1); {
loadSetting("FrontWingLabel", "FrontWingEdit", "FrontWingDefaultLabel", GfLogInfo("Opened car setup menu items file: %s\n", "carsetupmenuitems.xml");
hparmCar, hparmCarSetup, frontWing, SECT_FRNTWING, PRM_WINGANGLE,
"Front Wing Angle", "deg", 1); std::vector<std::string> sections = GfParmListGetSectionNamesList(hparmItems);
loadSetting("RearWingLabel", "RearWingEdit", "RearWingDefaultLabel",
hparmCar, hparmCarSetup, rearWing, SECT_REARWING, PRM_WINGANGLE, for (size_t i = 0; i < sections.size(); ++i)
"Rear Wing Angle", "deg", 1); {
loadSetting("RearDiffSlipLabel", "RearDiffSlipEdit", "RearDiffSlipDefaultLabel", std::string strSection = sections[i];
hparmCar, hparmCarSetup, rearDiffSlip, SECT_REARDIFFERENTIAL, PRM_MAX_SLIP_BIAS,
"Rear Diff Max Slip Bias", "%", 1); GfLogDebug("section %zu: %s\n", i, strSection.c_str());
loadSetting("RearDiffCoastSlipLabel", "RearDiffCoastSlipEdit", "RearDiffCoastSlipDefaultLabel",
hparmCar, hparmCarSetup, rearDiffCoastSlip, SECT_REARDIFFERENTIAL, PRM_COAST_MAX_SLIP_BIAS, size_t page = GfParmGetNum(hparmItems, strSection.c_str(), "page", "", 0);
"Rear Diff Coast Max Slip Bias", "%", 1); size_t index = GfParmGetNum(hparmItems, strSection.c_str(), "index", "", 0);
loadSetting("RearDiffRatioLabel", "RearDiffRatioEdit", "RearDiffRatioDefaultLabel",
hparmCar, hparmCarSetup, rearDiffRatio, SECT_REARDIFFERENTIAL, PRM_RATIO, if (page <= items.size())
"Rear Diff Ratio", "", 3); items.resize(page + 1);
if (index >= ITEMS_PER_PAGE)
{
GfLogError("Invalid index %zu\n", index);
continue;
}
attnum &att = items[page][index];
att.labelId = getDynamicControlId(std::string("Label" + std::to_string(index)).c_str());
att.editId = getDynamicControlId(std::string("Edit" + std::to_string(index)).c_str());
att.defaultLabelId = getDynamicControlId(std::string("DefaultLabel" + std::to_string(index)).c_str());
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;
// 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 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);
}
// Save the control id for all items.
for (size_t page = 0; page < items.size(); ++page)
{
for (size_t index = 0; index < ITEMS_PER_PAGE; ++index)
{
attnum &att = items[page][index];
if (!att.labelId)
att.labelId = getDynamicControlId(std::string("Label" + std::to_string(index)).c_str());
if (!att.editId)
att.editId = getDynamicControlId(std::string("Edit" + std::to_string(index)).c_str());
if (!att.defaultLabelId)
att.defaultLabelId = getDynamicControlId(std::string("DefaultLabel" + std::to_string(index)).c_str());
}
}
}
// Close the XML file of the car. // Close the XML file of the car.
GfParmReleaseHandle(hparmCar); GfParmReleaseHandle(hparmCar);
@ -246,19 +333,6 @@ void CarSetupMenu::loadSettings()
GfParmReleaseHandle(hparmCarSetup); GfParmReleaseHandle(hparmCarSetup);
} }
void CarSetupMenu::storeSetting(void *hparmCarSetup, attnum &att)
{
if (att.exists)
{
std::string strValue(GfuiEditboxGetString(getMenuHandle(), att.editId));
std::istringstream issValue(strValue);
issValue >> att.value;
GfParmSetNum(hparmCarSetup, att.section.c_str(), att.param.c_str(), att.units.c_str(),
att.value, att.minValue, att.maxValue);
}
}
// Save car setup to XML file. // Save car setup to XML file.
void CarSetupMenu::storeSettings() void CarSetupMenu::storeSettings()
{ {
@ -270,8 +344,6 @@ void CarSetupMenu::storeSettings()
void *hparmCarSetup = GfParmReadFile(ossCarSetupFileName.str().c_str(), GFPARM_RMODE_STD); void *hparmCarSetup = GfParmReadFile(ossCarSetupFileName.str().c_str(), GFPARM_RMODE_STD);
if (!hparmCarSetup) if (!hparmCarSetup)
{ {
GfLogInfo("Creating car setup file: %s\n", ossCarSetupFileName.str().c_str());
// Create the car setup file directory if it doesn't exist. // Create the car setup file directory if it doesn't exist.
std::string strDir = ossCarSetupFileName.str(); std::string strDir = ossCarSetupFileName.str();
strDir.resize(strDir.find_last_of('/')); strDir.resize(strDir.find_last_of('/'));
@ -294,14 +366,19 @@ void CarSetupMenu::storeSettings()
else else
GfLogInfo("Opened car setup file: %s\n", ossCarSetupFileName.str().c_str()); GfLogInfo("Opened car setup file: %s\n", ossCarSetupFileName.str().c_str());
storeSetting(hparmCarSetup, brakeRepartition); // Store all items.
storeSetting(hparmCarSetup, frontARB); for (size_t page = 0; page < items.size(); ++page)
storeSetting(hparmCarSetup, rearARB); {
storeSetting(hparmCarSetup, frontWing); for (size_t index = 0; index < ITEMS_PER_PAGE; ++index)
storeSetting(hparmCarSetup, rearWing); {
storeSetting(hparmCarSetup, rearDiffSlip); attnum &att = items[page][index];
storeSetting(hparmCarSetup, rearDiffCoastSlip); if (att.exists)
storeSetting(hparmCarSetup, rearDiffRatio); {
GfParmSetNum(hparmCarSetup, att.section.c_str(), att.param.c_str(), att.units.c_str(),
att.value, att.minValue, att.maxValue);
}
}
}
// Write the XML file of the car setup. // Write the XML file of the car setup.
GfParmWriteFile(NULL, hparmCarSetup, strCarId.c_str()); GfParmWriteFile(NULL, hparmCarSetup, strCarId.c_str());
@ -312,6 +389,7 @@ void CarSetupMenu::storeSettings()
CarSetupMenu::CarSetupMenu() CarSetupMenu::CarSetupMenu()
: GfuiMenuScreen("carsetupmenu.xml") : GfuiMenuScreen("carsetupmenu.xml")
, currentPage(0)
{ {
} }
@ -331,41 +409,20 @@ bool CarSetupMenu::initialize(void *pMenu, const GfRace *pRace, const GfDriver *
createLabelControl("CarNameLabel"); createLabelControl("CarNameLabel");
createLabelControl("BrakeBiasLabel"); // Create items.
createEditControl("BrakeBiasEdit", this, NULL, NULL); for (size_t index = 0; index < ITEMS_PER_PAGE; ++index)
createLabelControl("BrakeBiasDefaultLabel"); {
createLabelControl(std::string("Label" + std::to_string(index)).c_str());
createLabelControl("FrontARBLabel"); createEditControl(std::string("Edit" + std::to_string(index)).c_str(), this, NULL, NULL);
createEditControl("FrontARBEdit", this, NULL, NULL); createLabelControl(std::string("DefaultLabel" + std::to_string(index)).c_str());
createLabelControl("FrontARBDefaultLabel"); }
createLabelControl("RearARBLabel");
createEditControl("RearARBEdit", this, NULL, NULL);
createLabelControl("RearARBDefaultLabel");
createLabelControl("FrontWingLabel");
createEditControl("FrontWingEdit", this, NULL, NULL);
createLabelControl("FrontWingDefaultLabel");
createLabelControl("RearWingLabel");
createEditControl("RearWingEdit", this, NULL, NULL);
createLabelControl("RearWingDefaultLabel");
createLabelControl("RearDiffSlipLabel");
createEditControl("RearDiffSlipEdit", this, NULL, NULL);
createLabelControl("RearDiffSlipDefaultLabel");
createLabelControl("RearDiffCoastSlipLabel");
createEditControl("RearDiffCoastSlipEdit", this, NULL, NULL);
createLabelControl("RearDiffCoastSlipDefaultLabel");
createLabelControl("RearDiffRatioLabel");
createEditControl("RearDiffRatioEdit", this, NULL, NULL);
createLabelControl("RearDiffRatioDefaultLabel");
// Create buttons.
createButtonControl("ApplyButton", this, onAccept); createButtonControl("ApplyButton", this, onAccept);
createButtonControl("CancelButton", this, onCancel); createButtonControl("CancelButton", this, onCancel);
createButtonControl("ResetButton", this, onReset); createButtonControl("ResetButton", this, onReset);
createButtonControl("PreviousButton", this, onPrevious);
createButtonControl("NextButton", this, onNext);
closeXMLDescriptor(); closeXMLDescriptor();

View file

@ -28,6 +28,8 @@ class GfDriver;
class GfCar; class GfCar;
class GfTrack; class GfTrack;
#define ITEMS_PER_PAGE 10
class CarSetupMenu : public GfuiMenuScreen class CarSetupMenu : public GfuiMenuScreen
{ {
public: public:
@ -52,6 +54,8 @@ protected:
static void onAccept(void *pMenu); static void onAccept(void *pMenu);
static void onCancel(void *pMenu); static void onCancel(void *pMenu);
static void onReset(void *pMenu); static void onReset(void *pMenu);
static void onPrevious(void *pMenu);
static void onNext(void *pMenu);
// The target race. // The target race.
const GfRace *_pRace; const GfRace *_pRace;
@ -72,30 +76,20 @@ protected:
std::string section; std::string section;
std::string param; std::string param;
std::string units; std::string units;
std::string label;
int precision; int precision;
attnum() : attnum() :
labelId(0), editId(0), defaultLabelId(0), exists(false), labelId(0), editId(0), defaultLabelId(0), exists(false),
value(0), minValue(0), defaultValue(0), maxValue(0) value(0), minValue(0), defaultValue(0), maxValue(0), precision(0)
{ {
} }
}; };
void updateControl(const attnum &att); void readCurrentPage();
void loadSetting(const char *label, const char *edit, const char *defaultLabel,
void *hparmCar, void *hparmCarSetup, attnum &att,
const char *section, const char *param, const char *labelStr,
const char *units, int precision);
void storeSetting(void *hparmCarSetup, attnum &att);
attnum brakeRepartition; std::vector<std::array<attnum, ITEMS_PER_PAGE> > items;
attnum frontARB; size_t currentPage;
attnum rearARB;
attnum frontWing;
attnum rearWing;
attnum rearDiffSlip;
attnum rearDiffCoastSlip;
attnum rearDiffRatio;
}; };
#endif /* _CARSETUPMENU_H_ */ #endif /* _CARSETUPMENU_H_ */