38 #define INITDATA(key, type, name) data[key] = dashData_t(type, name) 
   40 DashBoardManager::DashBoardManager(
ActorPtr actor) : visible(true), m_actor(actor)
 
  141     MyGUI::ResourceManager::getInstance().load(
"MyGUI_FontsDash.xml");
 
  156     const char* s = str.c_str();
 
  157     for (
int i = 0; i < 
DD_MAX; i++)
 
  159         if (!strcmp(
data[i].name, s))
 
  167     if (
id > 0 && 
id < 
DD_MAX)
 
  184     std::regex rpm_regex(R
"((\d+)rpm)"); 
  186     if (std::regex_search(input, match, rpm_regex)) {
 
  187         std::string rpm = match[1];
 
  188         return std::atoi(rpm.c_str());
 
  195     std::regex xph_regex(R
"(([km])ph)"); 
  197     if (std::regex_search(input, match, xph_regex)) {
 
  198         return match[1].str()[0];
 
  211         this->filename = filename;
 
  220     Ogre::FileInfoListPtr filelist
 
  221         = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(entry->
resource_group, 
fmt::format(
"{}*.layout", basename));
 
  223     if (filelist->empty())
 
  233         return filelist->begin()->filename;
 
  258     std::vector<DashCandidateLayout> candidates;
 
  260     for (Ogre::FileInfo& fileinfo : *filelist)
 
  262         candidates.emplace_back(fileinfo.filename);
 
  266     float least_overshoot = std::numeric_limits<float>::max(); 
DashCandidateLayout* overshoot_candidate = 
nullptr;
 
  267     float least_undershoot = -std::numeric_limits<float>::max(); 
DashCandidateLayout* undershoot_candidate = 
nullptr;
 
  268     for (
auto& candidate : candidates)
 
  270         if (candidate.xph == desiredX)
 
  272             float rpm_diff = (float)candidate.
rpm - redlineRPM;
 
  273             if (rpm_diff < 0 && rpm_diff > least_undershoot)
 
  275                 least_undershoot = rpm_diff;
 
  276                 undershoot_candidate = &candidate;
 
  278             else if (rpm_diff >= 0 && rpm_diff < least_overshoot)
 
  280                 least_overshoot = rpm_diff;
 
  281                 overshoot_candidate = &candidate;
 
  286     if (overshoot_candidate)
 
  288         return overshoot_candidate->
filename;
 
  290     else if (undershoot_candidate)
 
  294         return undershoot_candidate->
filename;
 
  300     least_overshoot = std::numeric_limits<float>::max(); overshoot_candidate = 
nullptr;
 
  301     least_undershoot = -std::numeric_limits<float>::max(); undershoot_candidate = 
nullptr;
 
  302     for (
auto& candidate : candidates)
 
  304         float rpm_diff = (float)candidate.
rpm - redlineRPM;
 
  305         if (rpm_diff < 0 && rpm_diff > least_undershoot)
 
  307             least_undershoot = rpm_diff;
 
  308             undershoot_candidate = &candidate;
 
  310         else if (rpm_diff >= 0 && rpm_diff < least_overshoot)
 
  312             least_overshoot = rpm_diff;
 
  313             overshoot_candidate = &candidate;
 
  317     if (overshoot_candidate)
 
  319         return overshoot_candidate->
filename;
 
  321     else if (undershoot_candidate)
 
  325         return undershoot_candidate->
filename;
 
  328     return filelist->begin()->filename; 
 
  339     std::string basename, ext, layoutfname;
 
  340     Ogre::StringUtil::splitBaseFilename(filename, basename, ext);
 
  341     if (ext == 
"dashboard")
 
  347                 fmt::format(
"DashboardManager: Could not find dashboard file '{}'", filename));
 
  353         Ogre::FileInfoListPtr filelist
 
  354             = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(entry->
resource_group, 
fmt::format(
"{}*.resource", basename));
 
  355         for (Ogre::FileInfo& fileinfo : *filelist)
 
  357             MyGUI::ResourceManager::getInstance().load(fileinfo.filename);
 
  362         layoutfname = filename;
 
  365     if (layoutfname == 
"")
 
  413     switch (
data[key].type)
 
  430         if (!d->getIsTextureLayer())
 
  432             d->setVisible(visibility);
 
  441         if (d->getIsTextureLayer())
 
  443             d->setVisible(visibility, 
false);
 
  463     , mainWidget(nullptr)
 
  464     , textureLayer(_textureLayer)
 
  467     prefix = MyGUI::utility::toString(
this, 
"_");
 
  478     MyGUI::LayoutManager::getInstance().unloadLayout(
widgets);
 
  480     MyGUI::ResourceManager::getInstance().removeByName(
filename);
 
  570             String fn = String(
controls[i].texture) + String(
"-") + 
TOSTRING((
int)val) + String(
".png");
 
  621                 s = Ogre::StringConverter::toString(val);
 
  629                 if (strcmp(tmp, 
controls[i].format_neg_zero) == 0)
 
  634                 s = MyGUI::UString(tmp);
 
  655         TexturePtr tex = TextureManager::getSingleton().getByName(
"RTTTexture1");
 
  657             mainWidget->setSize(tex->getWidth(), tex->getHeight());
 
  661         MyGUI::IntSize screenSize = MyGUI::RenderManager::getInstance().getViewSize();
 
  668     std::string name = 
w->getName();
 
  669     std::string anim = 
w->getUserString(
"anim");
 
  670     std::string debug = 
w->getUserString(
"debug");
 
  671     std::string linkArgs = 
w->getUserString(
"link");
 
  674     w->setUserString(
"interactive", 
"0");
 
  678         w->setVisible(
false);
 
  683     if (name.size() > 
prefix.size())
 
  685         std::string prefixLessName = name.substr(
prefix.size());
 
  686         if (prefixLessName == 
"_Main")
 
  694         if (prefixLessName == 
"DEBUG")
 
  696             w->setVisible(
false);
 
  702     if (!linkArgs.empty())
 
  705         memset(&ctrl, 0, 
sizeof(ctrl));
 
  708             strncpy(ctrl.
name, name.c_str(), 255);
 
  718             String linkName = 
"";
 
  719             if (linkArgs.empty())
 
  721                 LOG(
"Dashboard ("+
filename+
"/"+name+
"): empty Link");
 
  726             if (linkArgs.find(
">") != linkArgs.npos)
 
  728                 Ogre::StringVector args = Ogre::StringUtil::split(linkArgs, 
">");
 
  729                 if (args.size() == 2)
 
  737                     LOG(
"Dashboard ("+
filename+
"/"+name+
"): error in conditional Link: " + linkArgs);
 
  741             else if (linkArgs.find(
"<") != linkArgs.npos)
 
  743                 Ogre::StringVector args = Ogre::StringUtil::split(linkArgs, 
"<");
 
  744                 if (args.size() == 2)
 
  752                     LOG(
"Dashboard ("+
filename+
"/"+name+
"): error in conditional Link: " + linkArgs);
 
  767                 LOG(
"Dashboard ("+
filename+
"/"+name+
"): unknown Link: " + linkName);
 
  775         ctrl.
wmin = StringConverter::parseReal(
w->getUserString(
"min"));
 
  776         ctrl.
wmax = StringConverter::parseReal(
w->getUserString(
"max"));
 
  777         ctrl.
vmin = StringConverter::parseReal(
w->getUserString(
"vmin"));
 
  778         ctrl.
vmax = StringConverter::parseReal(
w->getUserString(
"vmax"));
 
  780         String texture = 
w->getUserString(
"texture");
 
  781         if (!texture.empty())
 
  782             strncpy(ctrl.
texture, texture.c_str(), 255);
 
  784         String 
format = 
w->getUserString(
"format");
 
  788         String direction = 
w->getUserString(
"direction");
 
  789         if (direction == 
"right")
 
  791         else if (direction == 
"left")
 
  793         else if (direction == 
"down")
 
  795         else if (direction == 
"up")
 
  797         else if (!direction.empty())
 
  799             LOG(
"Dashboard ("+
filename+
"/"+name+
"): unknown direction: " + direction);
 
  803         if (anim == 
"rotate")
 
  819                 ctrl.
rotImg = 
w->getSubWidgetMain()->castType<MyGUI::RotatingSkin>();
 
  823                 LOG(
"Dashboard ("+
filename+
"/"+name+
"): Rotating controls must use the RotatingSkin");
 
  828                 LOG(
"Dashboard ("+
filename+
"/"+name+
"): error loading rotation control");
 
  833             ctrl.
rotImg->setCenter(MyGUI::IntPoint(
w->getHeight() * 0.5f, 
w->getWidth() * 0.5f));
 
  835         else if (anim == 
"scale")
 
  840                 LOG(
"Dashboard ("+
filename+
"/"+name+
"): direction empty: scale needs a direction");
 
  844         else if (anim == 
"translate")
 
  849                 LOG(
"Dashboard ("+
filename+
"/"+name+
"): direction empty: translate needs a direction");
 
  853         else if (anim == 
"series")
 
  856             ctrl.
img = (MyGUI::ImageBox *)
w; 
 
  859                 LOG(
"Dashboard ("+
filename+
"/"+name+
"): error loading series control");
 
  863         else if (anim == 
"textcolor" || anim == 
"textcolour")
 
  870                 ctrl.
txt = (MyGUI::TextBox *)
w;
 
  874                 LOG(
"Dashboard ("+
filename+
"/"+name+
"): textcolor controls must use the TextBox Control");
 
  878         else if (anim == 
"textformat")
 
  883                 ctrl.
txt = (MyGUI::TextBox *)
w; 
 
  887                 LOG(
"Dashboard ("+
filename+
"/"+name+
"): Lamp controls must use the ImageBox Control");
 
  894             if (std::strlen(ctrl.
format))
 
  899         else if (anim == 
"textstring")
 
  904                 ctrl.
txt = (MyGUI::TextBox *)
w; 
 
  908                 LOG(
"Dashboard ("+
filename+
"/"+name+
"): Lamp controls must use the ImageBox Control");
 
  913         else if (anim == 
"lamp")
 
  930             ctrl.
img = (MyGUI::ImageBox *)
w; 
 
  933                 LOG(
"Dashboard ("+
filename+
"/"+name+
"): error loading Lamp control");
 
  948     MyGUI::EnumeratorWidgetPtr e = 
w->getEnumerator();
 
  959     for (MyGUI::VectorWidgetPtr::iterator iter = 
widgets.begin(); iter != 
widgets.end(); ++iter)
 
  975         for (MyGUI::VectorWidgetPtr::iterator iter = 
widgets.begin(); iter != 
widgets.end(); ++iter)
 
  977             (*iter)->setVisible(v);