diff --git a/application.cpp b/application.cpp index 4680596c..8330e5bb 100644 --- a/application.cpp +++ b/application.cpp @@ -20,6 +20,7 @@ http://mozilla.org/MPL/2.0/. #include "sceneeditor.h" #include "renderer.h" #include "uilayer.h" +#include "translation.h" #include "logs.h" #ifdef EU07_BUILD_STATIC @@ -109,6 +110,9 @@ eu07_application::init( int Argc, char *Argv[] ) { if( ( result = init_settings( Argc, Argv ) ) != 0 ) { return result; } + if( ( result = init_locale() ) != 0 ) { + return result; + } WriteLog( "Starting MaSzyna rail vehicle simulator (release: " + Global.asVersion + ")" ); WriteLog( "For online documentation and additional files refer to: http://eu07.pl" ); @@ -368,6 +372,14 @@ eu07_application::init_settings( int Argc, char *Argv[] ) { return 0; } +int +eu07_application::init_locale() { + + locale::init(); + + return 0; +} + int eu07_application::init_glfw() { diff --git a/application.h b/application.h index d7cbea69..17f9048c 100644 --- a/application.h +++ b/application.h @@ -70,6 +70,7 @@ private: void init_debug(); void init_files(); int init_settings( int Argc, char *Argv[] ); + int init_locale(); int init_glfw(); void init_callbacks(); int init_gfx(); diff --git a/driveruilayer.cpp b/driveruilayer.cpp index 8057011a..a346adef 100644 --- a/driveruilayer.cpp +++ b/driveruilayer.cpp @@ -26,9 +26,13 @@ driver_ui::driver_ui() { push_back( &m_debugpanel ); push_back( &m_transcriptspanel ); + m_aidpanel.name = locale::strings[ locale::string::driver_aid_header ]; + + m_timetablepanel.name = locale::strings[ locale::string::driver_timetable_header ]; m_timetablepanel.size_min = { 435, 110 }; m_timetablepanel.size_max = { 435, Global.iWindowHeight * 0.95 }; + m_transcriptspanel.name = locale::strings[ locale::string::driver_transcripts_header ]; m_transcriptspanel.size_min = { 435, 85 }; m_transcriptspanel.size_max = { Global.iWindowWidth * 0.95, Global.iWindowHeight * 0.95 }; } @@ -141,14 +145,15 @@ driver_ui::render_() { auto const pausemask { 1 | 2 }; if( ( Global.iPause & pausemask ) != 0 ) { // pause/quit modal - auto const popupheader{ "Simulation Paused" }; + auto const popupheader { locale::strings[ locale::string::driver_pause_header ].c_str() }; ImGui::OpenPopup( popupheader ); if( ImGui::BeginPopupModal( popupheader, nullptr, ImGuiWindowFlags_AlwaysAutoResize ) ) { - if( ImGui::Button( "Resume", ImVec2( 120, 0 ) ) ) { + auto const popupwidth{ locale::strings[ locale::string::driver_pause_header ].size() * 7 }; + if( ImGui::Button( locale::strings[ locale::string::driver_pause_resume ].c_str(), ImVec2( popupwidth, 0 ) ) ) { ImGui::CloseCurrentPopup(); Global.iPause &= ~pausemask; } - if( ImGui::Button( "Quit", ImVec2( 120, 0 ) ) ) { + if( ImGui::Button( locale::strings[ locale::string::driver_pause_quit ].c_str(), ImVec2( popupwidth, 0 ) ) ) { ImGui::CloseCurrentPopup(); glfwSetWindowShouldClose( m_window, 1 ); } diff --git a/driveruipanels.cpp b/driveruipanels.cpp index 71d54c45..0e4b7ef3 100644 --- a/driveruipanels.cpp +++ b/driveruipanels.cpp @@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/. #include "translation.h" #include "simulation.h" #include "simulationtime.h" +#include "timer.h" #include "event.h" #include "camera.h" #include "mtable.h" @@ -26,6 +27,8 @@ http://mozilla.org/MPL/2.0/. #include "utilities.h" #include "logs.h" +#undef snprintf // defined by train.h->pyint.h->python + void drivingaid_panel::update() { @@ -43,84 +46,109 @@ drivingaid_panel::update() { auto const *driver = controlled->Mechanik; { // throttle, velocity, speed limits and grade - auto textline = - "Throttle: " + to_string( driver->Controlling()->MainCtrlPos, 0, 2 ) - + "+" + std::to_string( driver->Controlling()->ScndCtrlPos ) - + " " - + ( mover->ActiveDir > 0 ? 'D' : - mover->ActiveDir < 0 ? 'R' : - 'N' ); - + std::string expandedtext; if( is_expanded ) { - - auto const speedlimit { static_cast( std::floor( driver->VelDesired ) ) }; - textline += - " Speed: " + std::to_string( static_cast( std::floor( mover->Vel ) ) ) + " km/h" - + " (limit: " + std::to_string( speedlimit ) + " km/h"; - auto const nextspeedlimit { static_cast( std::floor( driver->VelNext ) ) }; - if( nextspeedlimit != speedlimit ) { - textline += - ", new limit: " + std::to_string( nextspeedlimit ) + " km/h" - + " in " + to_string( driver->ActualProximityDist * 0.001, 1 ) + " km"; - } - textline += ")"; + // grade + std::string gradetext; auto const reverser { ( mover->ActiveDir > 0 ? 1 : -1 ) }; auto const grade { controlled->VectorFront().y * 100 * ( controlled->DirectionGet() == reverser ? 1 : -1 ) * reverser }; if( std::abs( grade ) >= 0.25 ) { - textline += " Grade: " + to_string( grade, 1 ) + "%%"; + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::driver_aid_grade ].c_str(), + grade ); + gradetext = m_buffer.data(); } + // next speed limit + auto const speedlimit { static_cast( std::floor( driver->VelDesired ) ) }; + auto const nextspeedlimit { static_cast( std::floor( driver->VelNext ) ) }; + std::string nextspeedlimittext; + if( nextspeedlimit != speedlimit ) { + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::driver_aid_nextlimit ].c_str(), + nextspeedlimit, + driver->ActualProximityDist * 0.001 ); + nextspeedlimittext = m_buffer.data(); + } + // current speed and limit + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::driver_aid_speedlimit ].c_str(), + static_cast( std::floor( mover->Vel ) ), + speedlimit, + nextspeedlimittext.c_str(), + gradetext.c_str() ); + expandedtext = m_buffer.data(); } + // base data and optional bits put together + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::driver_aid_throttle ].c_str(), + driver->Controlling()->MainCtrlPos, + driver->Controlling()->ScndCtrlPos, + ( mover->ActiveDir > 0 ? 'D' : mover->ActiveDir < 0 ? 'R' : 'N' ), + expandedtext.c_str()); - text_lines.emplace_back( textline, Global.UITextColor ); + text_lines.emplace_back( m_buffer.data(), Global.UITextColor ); } { // brakes, air pressure - auto textline = - "Brakes:" + to_string( mover->fBrakeCtrlPos, 1, 5 ) - + "+" + to_string( mover->LocalBrakePosA * LocalBrakePosNo, 0 ) - + ( mover->SlippingWheels ? " !" : " " ); - if( textline.size() > 16 ) { - textline.erase( 16 ); - } - + std::string expandedtext; if( is_expanded ) { - - textline += - " Pressure: " + to_string( mover->BrakePress * 100.0, 2 ) + " kPa" - + " (train pipe: " + to_string( mover->PipePress * 100.0, 2 ) + " kPa)"; + std::snprintf ( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::driver_aid_pressures ].c_str(), + mover->BrakePress * 100, + mover->PipePress * 100 ); + expandedtext = m_buffer.data(); } + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::driver_aid_brakes ].c_str(), + mover->fBrakeCtrlPos, + mover->LocalBrakePosA * LocalBrakePosNo, + ( mover->SlippingWheels ? '!' : ' ' ), + expandedtext.c_str() ); - text_lines.emplace_back( textline, Global.UITextColor ); + text_lines.emplace_back( m_buffer.data(), Global.UITextColor ); } { // alerter, hints - std::string textline = - ( true == TestFlag( mover->SecuritySystem.Status, s_aware ) ? - "!ALERTER! " : - " " ); - textline += - ( true == TestFlag( mover->SecuritySystem.Status, s_active ) ? - "!SHP! " : - " " ); - + std::string expandedtext; if( is_expanded ) { - auto const stoptime { static_cast( -1.0 * controlled->Mechanik->fStopTime ) }; if( stoptime > 0 ) { - textline += " Loading/unloading in progress (" + to_string( stoptime ) + ( stoptime > 1 ? " seconds" : " second" ) + " left)"; + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::driver_aid_loadinginprogress ].c_str(), + stoptime ); + expandedtext = m_buffer.data(); } else { - auto const trackblockdistance { std::abs( controlled->Mechanik->TrackBlock() ) }; + auto const trackblockdistance{ std::abs( controlled->Mechanik->TrackBlock() ) }; if( trackblockdistance <= 75.0 ) { - textline += " Another vehicle ahead (distance: " + to_string( trackblockdistance, 1 ) + " m)"; + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::driver_aid_vehicleahead ].c_str(), + trackblockdistance ); + expandedtext = m_buffer.data(); } } } + std::string textline = + ( true == TestFlag( mover->SecuritySystem.Status, s_aware ) ? + locale::strings[ locale::string::driver_aid_alerter ] : + " " ); + textline += + ( true == TestFlag( mover->SecuritySystem.Status, s_active ) ? + locale::strings[ locale::string::driver_aid_shp ] : + " " ); - text_lines.emplace_back( textline, Global.UITextColor ); + text_lines.emplace_back( textline + " " + expandedtext, Global.UITextColor ); } - auto const sizex = ( is_expanded ? 660 : 130 ); + auto const sizex = ( is_expanded ? 660 : 135 ); size = { sizex, 85 }; } @@ -137,13 +165,14 @@ timetable_panel::update() { auto const &time { simulation::Time.data() }; { // current time - auto textline = - "Time: " - + to_string( time.wHour ) + ":" - + ( time.wMinute < 10 ? "0" : "" ) + to_string( time.wMinute ) + ":" - + ( time.wSecond < 10 ? "0" : "" ) + to_string( time.wSecond ); + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::driver_timetable_time ].c_str(), + time.wHour, + time.wMinute, + time.wSecond ); - text_lines.emplace_back( textline, Global.UITextColor ); + text_lines.emplace_back( m_buffer.data(), Global.UITextColor ); } auto *vehicle { @@ -187,7 +216,7 @@ timetable_panel::update() { if( 0 == table->StationCount ) { // only bother if there's stations to list - text_lines.emplace_back( "(no timetable)", Global.UITextColor ); + text_lines.emplace_back( locale::strings[ locale::string::driver_timetable_notimetable ], Global.UITextColor ); } else { auto const readycolor { glm::vec4( 84.0f / 255.0f, 164.0f / 255.0f, 132.0f / 255.0f, 1.f ) }; @@ -314,7 +343,7 @@ debug_panel::render() { if( size_min.x > 0 ) { ImGui::SetNextWindowSizeConstraints( ImVec2( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) ); } - if( true == ImGui::Begin( name.c_str(), &is_open, flags ) ) { + if( true == ImGui::Begin( identifier.c_str(), &is_open, flags ) ) { // header section for( auto const &line : text_lines ) { ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() ); @@ -345,180 +374,160 @@ debug_panel::update_section_vehicle( std::vector &Output ) { auto const &vehicle { *m_input.vehicle }; auto const &mover { *m_input.mover }; - // f3 data - auto textline = "Name: " + mover.Name; + auto const isowned { ( vehicle.Mechanik == nullptr ) && ( vehicle.ctOwner != nullptr ) }; + auto const isplayervehicle { ( m_input.train != nullptr ) && ( m_input.train->Dynamic() == m_input.vehicle ) }; + auto const isdieselenginepowered { ( mover.EngineType == TEngineType::DieselElectric ) || ( mover.EngineType == TEngineType::DieselEngine ) }; + auto const isdieselinshuntmode { mover.ShuntMode && mover.EngineType == TEngineType::DieselElectric }; - if( ( vehicle.Mechanik == nullptr ) && ( vehicle.ctOwner ) ) { - // for cars other than leading unit indicate the leader - textline += ", owned by " + vehicle.ctOwner->OwnerName(); - } - textline += "\nLoad: " + to_string( mover.Load, 0 ) + ' ' + mover.LoadType; - textline += "\nStatus: " + mover.EngineDescription( 0 ); - if( mover.WheelFlat > 0.01 ) { - textline += " Flat: " + to_string( mover.WheelFlat, 1 ) + " mm"; - } + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::debug_vehicle_nameloadstatuscouplers ].c_str(), + mover.Name.c_str(), + std::string( isowned ? locale::strings[ locale::string::debug_vehicle_owned ].c_str() + vehicle.ctOwner->OwnerName() : "" ).c_str(), + mover.Load, + mover.LoadType.c_str(), + mover.EngineDescription( 0 ).c_str(), + // TODO: put wheel flat reporting in the enginedescription() + std::string( mover.WheelFlat > 0.01 ? " Flat: " + to_string( mover.WheelFlat, 1 ) + " mm" : "" ).c_str(), + update_vehicle_coupler( side::front ).c_str(), + update_vehicle_coupler( side::rear ).c_str() ); - // informacja o sprzęgach - textline += - "\nCouplers:\n front: " + - ( vehicle.PrevConnected ? - vehicle.PrevConnected->name() + " [" + to_string( mover.Couplers[ 0 ].CouplingFlag ) + "]" + ( - mover.Couplers[ 0 ].CouplingFlag == 0 ? - " (" + to_string( mover.Couplers[ 0 ].CoupleDist, 1 ) + " m)" : - "" ) : - "none" ) - + "\n rear: " + - ( vehicle.NextConnected ? - vehicle.NextConnected->name() + " [" + to_string( mover.Couplers[ 1 ].CouplingFlag ) + "]" + ( - mover.Couplers[ 1 ].CouplingFlag == 0 ? - " (" + to_string( mover.Couplers[ 1 ].CoupleDist, 1 ) + " m)" : - "" ) : - "none" ); + Output.emplace_back( std::string{ m_buffer.data() }, Global.UITextColor ); - Output.emplace_back( textline, Global.UITextColor ); + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::debug_vehicle_devicespower ].c_str(), + // devices + ( mover.Battery ? 'B' : '.' ), + ( mover.Mains ? 'M' : '.' ), + ( mover.FuseFlag ? '!' : '.' ), + ( mover.PantRearUp ? ( mover.PantRearVolt > 0.0 ? 'O' : 'o' ) : '.' ), + ( mover.PantFrontUp ? ( mover.PantFrontVolt > 0.0 ? 'P' : 'p' ) : '.' ), + ( mover.PantPressLockActive ? '!' : ( mover.PantPressSwitchActive ? '*' : '.' ) ), + ( mover.WaterPump.is_active ? 'W' : ( false == mover.WaterPump.breaker ? '-' : ( mover.WaterPump.is_enabled ? 'w' : '.' ) ) ), + ( true == mover.WaterHeater.is_damaged ? '!' : ( mover.WaterHeater.is_active ? 'H' : ( false == mover.WaterHeater.breaker ? '-' : ( mover.WaterHeater.is_enabled ? 'h' : '.' ) ) ) ), + ( mover.FuelPump.is_active ? 'F' : ( mover.FuelPump.is_enabled ? 'f' : '.' ) ), + ( mover.OilPump.is_active ? 'O' : ( mover.OilPump.is_enabled ? 'o' : '.' ) ), + ( false == mover.ConverterAllowLocal ? '-' : ( mover.ConverterAllow ? ( mover.ConverterFlag ? 'X' : 'x' ) : '.' ) ), + ( mover.ConvOvldFlag ? '!' : '.' ), + ( mover.CompressorFlag ? 'C' : ( false == mover.CompressorAllowLocal ? '-' : ( ( mover.CompressorAllow || mover.CompressorStart == start_t::automatic ) ? 'c' : '.' ) ) ), + ( mover.CompressorGovernorLock ? '!' : '.' ), + std::string( isplayervehicle ? locale::strings[ locale::string::debug_vehicle_radio ] + ( mover.Radio ? std::to_string( m_input.train->RadioChannel() ) : "-" ) : "" ).c_str(), + std::string( isdieselenginepowered ? locale::strings[ locale::string::debug_vehicle_oilpressure ] + to_string( mover.OilPump.pressure_present, 2 ) : "" ).c_str(), + // power transfers + mover.Couplers[ side::front ].power_high.voltage, + mover.Couplers[ side::front ].power_high.current, + std::string( mover.Couplers[ side::front ].power_high.local ? "" : "-" ).c_str(), + std::string( vehicle.DirectionGet() ? ":<<:" : ":>>:" ).c_str(), + std::string( mover.Couplers[ side::rear ].power_high.local ? "" : "-" ).c_str(), + mover.Couplers[ side::rear ].power_high.voltage, + mover.Couplers[ side::rear ].power_high.current ); - // equipment flags - textline = "Devices: "; - textline += ( mover.Battery ? "B" : "." ); - textline += ( mover.Mains ? "M" : "." ); - textline += ( mover.FuseFlag ? "!" : "." ); - textline += ( mover.PantRearUp ? ( mover.PantRearVolt > 0.0 ? "O" : "o" ) : "." ); - textline += ( mover.PantFrontUp ? ( mover.PantFrontVolt > 0.0 ? "P" : "p" ) : "." ); - textline += ( mover.PantPressLockActive ? "!" : ( mover.PantPressSwitchActive ? "*" : "." ) ); - textline += ( mover.WaterPump.is_active ? "W" : ( false == mover.WaterPump.breaker ? "-" : ( mover.WaterPump.is_enabled ? "w" : "." ) ) ); - textline += ( true == mover.WaterHeater.is_damaged ? "!" : ( mover.WaterHeater.is_active ? "H" : ( false == mover.WaterHeater.breaker ? "-" : ( mover.WaterHeater.is_enabled ? "h" : "." ) ) ) ); - textline += ( mover.FuelPump.is_active ? "F" : ( mover.FuelPump.is_enabled ? "f" : "." ) ); - textline += ( mover.OilPump.is_active ? "O" : ( mover.OilPump.is_enabled ? "o" : "." ) ); - textline += ( false == mover.ConverterAllowLocal ? "-" : ( mover.ConverterAllow ? ( mover.ConverterFlag ? "X" : "x" ) : "." ) ); - textline += ( mover.ConvOvldFlag ? "!" : "." ); - textline += ( mover.CompressorFlag ? "C" : ( false == mover.CompressorAllowLocal ? "-" : ( ( mover.CompressorAllow || mover.CompressorStart == start_t::automatic ) ? "c" : "." ) ) ); - textline += ( mover.CompressorGovernorLock ? "!" : "." ); + Output.emplace_back( m_buffer.data(), Global.UITextColor ); - if( ( m_input.train != nullptr ) && ( m_input.train->Dynamic() == m_input.vehicle ) ) { - textline += " radio: " + ( mover.Radio ? std::to_string( m_input.train->RadioChannel() ) : "(off)" ); - } - if( ( mover.EngineType == TEngineType::DieselElectric ) - || ( mover.EngineType == TEngineType::DieselEngine ) ) { - textline += ", oil pressure: " + to_string( mover.OilPump.pressure_present, 2 ); - } + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::debug_vehicle_controllersenginerevolutions ].c_str(), + // controllers + mover.MainCtrlPos, + mover.MainCtrlActualPos, + std::string( isdieselinshuntmode ? to_string( mover.AnPos, 2 ) + locale::strings[ locale::string::debug_vehicle_shuntmode ] : std::to_string( mover.ScndCtrlPos ) + "(" + std::to_string( mover.ScndCtrlActualPos ) + ")" ).c_str(), + // engine + mover.EnginePower, + ( mover.TrainType == dt_EZT ? mover.ShowCurrent( 0 ) : mover.Im ), + // revolutions + mover.enrot * 60, + std::abs( mover.nrot ) * mover.Transmision.Ratio * 60, + mover.RventRot * 60, + mover.dizel_heat.rpmw, + mover.dizel_heat.rpmw2 ); - auto const frontcouplerhighvoltage = - to_string( mover.Couplers[ side::front ].power_high.voltage, 0 ) - + "@" - + to_string( mover.Couplers[ side::front ].power_high.current, 0 ); - auto const rearcouplerhighvoltage = - to_string( mover.Couplers[ side::rear ].power_high.voltage, 0 ) - + "@" - + to_string( mover.Couplers[ side::rear ].power_high.current, 0 ); + std::string textline { m_buffer.data() }; - textline += "\nPower transfers: "; - if( mover.Couplers[ side::front ].power_high.local == false ) { - textline += - "(" + frontcouplerhighvoltage + ")-" - + ":F" + ( vehicle.DirectionGet() ? "<<" : ">>" ) + "R:" - + "-(" + rearcouplerhighvoltage + ")"; - } - else { - textline += - frontcouplerhighvoltage - + ":F" + ( vehicle.DirectionGet() ? "<<" : ">>" ) + "R:" - + rearcouplerhighvoltage; - } + if( isdieselenginepowered ) { + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::debug_vehicle_temperatures ].c_str(), + mover.dizel_heat.Ts, + mover.dizel_heat.To, + mover.dizel_heat.temperatura1, + ( mover.WaterCircuitsLink ? '-' : '|' ), + mover.dizel_heat.temperatura2 ); + textline += m_buffer.data(); + } - Output.emplace_back( textline, Global.UITextColor ); + Output.emplace_back( textline, Global.UITextColor ); - textline = "Controllers:\n master: " + std::to_string( mover.MainCtrlPos ) + "(" + std::to_string( mover.MainCtrlActualPos ) + ")" - + ", secondary: " + - ( ( mover.ShuntMode && mover.EngineType == TEngineType::DieselElectric ) ? - to_string( mover.AnPos, 2 ) + " (shunt mode)" : - std::to_string( mover.ScndCtrlPos ) + "(" + std::to_string( mover.ScndCtrlActualPos ) + ")" ); + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::debug_vehicle_brakespressures ].c_str(), + // brakes + mover.fBrakeCtrlPos, + mover.LocalBrakePosA, + update_vehicle_brake().c_str(), + mover.LoadFlag, + // cylinders + mover.BrakePress, + mover.LocBrakePress, + mover.Hamulec->GetBrakeStatus(), + // pipes + mover.PipePress, + mover.BrakeCtrlPos2, + mover.ScndPipePress, + mover.CntrlPipePress, + // tanks + mover.Volume, + mover.Compressor, + mover.Hamulec->GetCRP() ); - textline += "\nEngine output: " + to_string( mover.EnginePower, 1 ); - textline += ", current: " + - ( mover.TrainType == dt_EZT ? - std::to_string( int( mover.ShowCurrent( 0 ) ) ) : - std::to_string( int( mover.Im ) ) ); + textline = m_buffer.data(); - textline += "\nRevolutions:\n engine: " + to_string( mover.enrot * 60, 0 ) - + ", motors: " + to_string( std::abs( mover.nrot ) * mover.Transmision.Ratio * 60, 0 ) - + ", ventilators: " + to_string( mover.RventRot * 60, 0 ) - + ", fans: " + to_string( mover.dizel_heat.rpmw, 0 ) + "+" + to_string( mover.dizel_heat.rpmw2, 0 ); - if( ( mover.EngineType == TEngineType::DieselElectric ) - || ( mover.EngineType == TEngineType::DieselEngine ) ) { - textline += - "\nTemperatures:\n engine: " + to_string( mover.dizel_heat.Ts, 2 ) - + ", oil: " + to_string( mover.dizel_heat.To, 2 ) - + ", water: " + to_string( mover.dizel_heat.temperatura1, 2 ) - + ( mover.WaterCircuitsLink ? "-" : "|" ) - + to_string( mover.dizel_heat.temperatura2, 2 ); - } + if( mover.EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) { + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::debug_vehicle_pantograph ].c_str(), + mover.PantPress, + ( mover.bPantKurek3 ? '-' : '|' ) ); + textline += m_buffer.data(); + } - Output.emplace_back( textline, Global.UITextColor ); + Output.emplace_back( textline, Global.UITextColor ); - textline = "Brakes:\n train: " + to_string( mover.fBrakeCtrlPos, 2 ) - + ", independent: " + to_string( mover.LocalBrakePosA, 2 ) - + ", delay: "; - if( ( mover.BrakeDelayFlag & bdelay_G ) == bdelay_G ) - textline += "G"; - if( ( mover.BrakeDelayFlag & bdelay_P ) == bdelay_P ) - textline += "P"; - if( ( mover.BrakeDelayFlag & bdelay_R ) == bdelay_R ) - textline += "R"; - if( ( mover.BrakeDelayFlag & bdelay_M ) == bdelay_M ) - textline += "+Mg"; - textline += ", load flag: " + to_string( mover.LoadFlag, 0 ); + if( tprev != simulation::Time.data().wSecond ) { + tprev = simulation::Time.data().wSecond; + Acc = ( mover.Vel - VelPrev ) / 3.6; + VelPrev = mover.Vel; + } + + std::snprintf( + m_buffer.data(), m_buffer.size(), + locale::strings[ locale::string::debug_vehicle_forcesaccelerationvelocityposition ].c_str(), + // forces + mover.Ft * 0.001f * ( mover.ActiveCab ? mover.ActiveCab : vehicle.ctOwner ? vehicle.ctOwner->Controlling()->ActiveCab : 1 ) + 0.001f, + mover.Fb * 0.001f, + mover.Adhesive( mover.RunningTrack.friction ), + ( mover.SlippingWheels ? " (!)" : "" ), + // acceleration + Acc, + mover.AccN + 0.001f, + std::string( std::abs( mover.RunningShape.R ) > 10000.0 ? "~0.0" : to_string( mover.RunningShape.R, 0 ) ).c_str(), + // velocity + vehicle.GetVelocity(), + mover.DistCounter, + // position + vehicle.GetPosition().x, + vehicle.GetPosition().y, + vehicle.GetPosition().z ); + + Output.emplace_back( m_buffer.data(), Global.UITextColor ); +/* + textline = " TC:" + to_string( mover.TotalCurrent, 0 ); +*/ /* if( mover.ManualBrakePos > 0 ) { textline += "; manual brake on"; } -*/ - textline += "\nBrake cylinder pressures:\n train: " + to_string( mover.BrakePress, 2 ) - + ", independent: " + to_string( mover.LocBrakePress, 2 ) - + ", status: " + to_hex_str( mover.Hamulec->GetBrakeStatus(), 2 ); - - textline += "\nPipe pressures:\n brake: " + to_string( mover.PipePress, 2 ) - + " (hat: " + to_string( mover.BrakeCtrlPos2, 2 ) + ")" - + ", main: " + to_string( mover.ScndPipePress, 2 ) - + ", control: " + to_string( mover.CntrlPipePress, 2 ); - - textline += "\nTank pressures:\n brake: " + to_string( mover.Volume, 2 ) - + ", main: " + to_string( mover.Compressor, 2 ) - + ", control: " + to_string( mover.Hamulec->GetCRP(), 2 ); - if( mover.EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) { - textline += ", pantograph: " + to_string( mover.PantPress, 2 ) + ( mover.bPantKurek3 ? "-MT" : "|MT" ); - } - - Output.emplace_back( textline, Global.UITextColor ); - - textline = "Forces:\n tractive: " + to_string( - mover.Ft * 0.001f * ( - mover.ActiveCab ? mover.ActiveCab : - vehicle.ctOwner ? vehicle.ctOwner->Controlling()->ActiveCab : - 1 ) + 0.001f, 1 ) - + ", brake: " + to_string( mover.Fb * 0.001f, 1 ) - + ", friction: " + to_string( mover.Adhesive( mover.RunningTrack.friction ), 2 ) - + ( mover.SlippingWheels ? " (!)" : "" ); - - if( tprev != simulation::Time.data().wSecond ) { - tprev = simulation::Time.data().wSecond; - Acc = ( mover.Vel - VelPrev ) / 3.6; - VelPrev = mover.Vel; - } - - textline += "\nAcceleration:\n tangential: " + to_string( Acc, 2 ) - + ", normal: " + to_string( mover.AccN, 2 ) - + " (path radius: " + ( std::abs( mover.RunningShape.R ) > 10000.0 ? - "~0.0" : - to_string( mover.RunningShape.R, 0 ) ) + ")"; - - textline += "\nVelocity: " + to_string( vehicle.GetVelocity(), 2 ) + " / " + to_string( mover.nrot* M_PI * mover.WheelDiameter * 3.6, 2 ) - + ", distance traveled: " + to_string( mover.DistCounter, 2 ) - + "\nPosition: [" + to_string( vehicle.GetPosition().x, 2 ) + ", " + to_string( vehicle.GetPosition().y, 2 ) + ", " + to_string( vehicle.GetPosition().z, 2 ) + "]"; - - Output.emplace_back( textline, Global.UITextColor ); -/* - textline = " TC:" + to_string( mover.TotalCurrent, 0 ); */ /* // McZapkie: warto wiedziec w jakim stanie sa przelaczniki @@ -544,6 +553,52 @@ debug_panel::update_section_vehicle( std::vector &Output ) { */ } +std::string +debug_panel::update_vehicle_coupler( int const Side ) { + // NOTE: mover and vehicle are guaranteed to be valid by the caller + std::string couplerstatus { locale::strings[ locale::string::debug_vehicle_none ] }; + + auto const *connected { ( + Side == side::front ? + m_input.vehicle->PrevConnected : + m_input.vehicle->NextConnected ) }; + + if( connected == nullptr ) { return couplerstatus; } + + auto const &mover { *( m_input.mover ) }; + + std::snprintf( + m_buffer.data(), m_buffer.size(), + "%s [%d]%s", + connected->name().c_str(), + mover.Couplers[ Side ].CouplingFlag, + std::string( mover.Couplers[ Side ].CouplingFlag == 0 ? " (" + to_string( mover.Couplers[ Side ].CoupleDist, 1 ) + " m)" : "" ).c_str() ); + + return { m_buffer.data() }; +} + +std::string +debug_panel::update_vehicle_brake() const { + // NOTE: mover is guaranteed to be valid by the caller + auto const &mover { *( m_input.mover ) }; + + std::string brakedelay; + + std::vector> delays { + { bdelay_G, "G" }, + { bdelay_P, "P" }, + { bdelay_R, "R" }, + { bdelay_M, "+Mg" } }; + + for( auto const &delay : delays ) { + if( ( mover.BrakeDelayFlag & delay.first ) == delay.first ) { + brakedelay += delay.second; + } + } + + return brakedelay; +} + void debug_panel::update_section_engine( std::vector &Output ) { @@ -672,7 +727,7 @@ debug_panel::update_section_ai( std::vector &Output ) { "Acceleration:\n desired: " + to_string( mechanik.AccDesired, 2 ) + ", corrected: " + to_string( mechanik.AccDesired * mechanik.BrakeAccFactor(), 2 ) + "\n current: " + to_string( mechanik.AbsAccS_pub, 2 ) - + ", slope: " + to_string( mechanik.fAccGravity, 2 ) + " (" + ( mechanik.fAccGravity > 0.01 ? "\\" : ( mechanik.fAccGravity < -0.01 ? "/" : "-" ) ) + ")" + + ", slope: " + to_string( mechanik.fAccGravity + 0.001f, 2 ) + " (" + ( mechanik.fAccGravity > 0.01 ? "\\" : ( mechanik.fAccGravity < -0.01 ? "/" : "-" ) ) + ")" + "\n brake threshold: " + to_string( mechanik.fAccThreshold, 2 ) + ", delays: " + to_string( mechanik.fBrake_a0[ 0 ], 2 ) + "+" + to_string( mechanik.fBrake_a1[ 0 ], 2 ); @@ -872,7 +927,12 @@ transcripts_panel::render() { if( size_min.x > 0 ) { ImGui::SetNextWindowSizeConstraints( ImVec2( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) ); } - if( true == ImGui::Begin( name.c_str(), &is_open, flags ) ) { + auto const panelname { ( + name.empty() ? + identifier : + name ) + + "###" + identifier }; + if( true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) { // header section for( auto const &line : text_lines ) { ImGui::TextWrapped( line.data.c_str() ); diff --git a/driveruipanels.h b/driveruipanels.h index 60315500..8f6e402c 100644 --- a/driveruipanels.h +++ b/driveruipanels.h @@ -22,6 +22,10 @@ public: void update() override; bool is_expanded { false }; + +private: +// members + std::array m_buffer; }; class timetable_panel : public ui_panel { @@ -33,6 +37,10 @@ public: void update() override; bool is_expanded{ false }; + +private: + // members + std::array m_buffer; }; class debug_panel : public ui_panel { @@ -64,9 +72,13 @@ private: void update_section_eventqueue( std::vector &Output ); void update_section_camera( std::vector &Output ); void update_section_renderer( std::vector &Output ); + // section update helpers + std::string update_vehicle_coupler( int const Side ); + std::string update_vehicle_brake() const; // renders provided lines, under specified collapsing header void render_section( std::string const &Header, std::vector const &Lines ); // members + std::array m_buffer; input_data m_input; std::vector m_vehiclelines, diff --git a/editoruipanels.cpp b/editoruipanels.cpp index fdc642a0..1facdf69 100644 --- a/editoruipanels.cpp +++ b/editoruipanels.cpp @@ -186,7 +186,7 @@ itemproperties_panel::render() { if( size_min.x > 0 ) { ImGui::SetNextWindowSizeConstraints( ImVec2( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) ); } - if( true == ImGui::Begin( name.c_str(), nullptr, flags ) ) { + if( true == ImGui::Begin( identifier.c_str(), nullptr, flags ) ) { // header section for( auto const &line : text_lines ) { ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() ); diff --git a/stdafx.h b/stdafx.h index 74568b22..194b7018 100644 --- a/stdafx.h +++ b/stdafx.h @@ -31,6 +31,7 @@ // stl #include #include +#include #include #define _USE_MATH_DEFINES #include diff --git a/translation.cpp b/translation.cpp index efa9efaf..bc5bc9d0 100644 --- a/translation.cpp +++ b/translation.cpp @@ -14,8 +14,103 @@ http://mozilla.org/MPL/2.0/. #include "stdafx.h" #include "translation.h" +#include "globals.h" + namespace locale { +void +init() { + // TODO: import localized strings from localization files + std::unordered_map> stringmap; + + stringmap.insert( + { "en", + { + "Driving Aid", + "Throttle: %2d+%d %c%s", + " Speed: %d km/h (limit %d km/h%s)%s", + ", new limit: %d km/h in %.1f km", + " Grade: %.1f%%", + "Brakes: %4.1f+%-2.0f%c%s", + " Pressure: %.2f kPa (train pipe: %.2f kPa)", + "!ALERTER! ", + "!SHP!", + " Loading/unloading in progress (%d s left)", + " Another vehicle ahead (distance: %.1f m)", + + "Timetable", + "Time: %d:%02d:%02d", + "(no timetable)", + + "Transcripts", + + "Simulation Paused", + "Resume", + "Quit", + + "Name: %s%s\nLoad: %d %s\nStatus: %s%s\nCouplers:\n front: %s\n rear: %s", + ", owned by: ", + "none", + "Devices: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%s%s\nPower transfers: %.0f@%.0f%s%s%s%.0f@%.0f", + " radio: ", + " oil pressure: ", + "Controllers:\n master: %d(%d), secondary: %s\nEngine output: %.1f, current: %.0f\nRevolutions:\n engine: %.0f, motors: %.0f, ventilators: %.0f, fans: %.0f+%.0f", + " (shunt mode)", + "\nTemperatures:\n engine: %.2f, oil: %.2f, water: %.2f%c%.2f", + "Brakes:\n train: %.2f, independent: %.2f, delay: %s, load flag: %d\nBrake cylinder pressures:\n train: %.2f, independent: %.2f, status: 0x%.2x\nPipe pressures:\n brake: %.2f (hat: %.2f), main: %.2f, control: %.2f\nTank pressures:\n auxiliary: %.2f, main: %.2f, control: %.2f", + " pantograph: %.2f%cMT", + "Forces:\n tractive: %.1f, brake: %.1f, friction: %.2f%s\nAcceleration:\n tangential: %.2f, normal: %.2f (path radius: %s)\nVelocity: %.2f, distance traveled: %.2f\nPosition: [%.2f, %.2f, %.2f]" + } + } ); + + stringmap.insert( + { "pl", + { + "Pomocnik", + "Nastawnik: %2d+%d %c%s", + " Predkosc: %d km/h (limit %d km/h%s)%s", + ", nowy limit: %d km/h za %.1f km", + " Pochylenie: %.1f%%", + "Hamulce: %4.1f+%-2.0f%c%s", + " Cisnienie: %.2f kPa (przewod glowny: %.2f kPa)", + "!CZUWAK! ", + "!SHP!", + " Wsiadanie/wysiadanie pasazerow (do zakonczenia %d s)", + " Inny pojazd na drodze (odleglosc: %.1f m)", + + "Rozklad jazdy", + "Godzina: %d:%02d:%02d", + "(brak rozkladu)", + + "Transkrypcje", + + "Symulacja wstrzymana", + "Wznow", + "Zakoncz", + + "Nazwa: %s%s\nLadunek: %d %s\nStatus: %s%s\nSprzegi:\n przedni: %s\n tylny: %s", + ", wlasciciel: ", + "wolny", + "Urzadzenia: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%s%s\nTransfer pradow: %.0f@%.0f%s%s%s%.0f@%.0f", + " radio: ", + " cisn.oleju: ", + "Nastawniki:\n glowny: %d(%d), dodatkowy: %s\nMoc silnika: %.1f, prad silnika: %.0f\nObroty:\n silnik: %.0f, motory: %.0f, went.silnika: %.0f, went.chlodnicy: %.0f+%.0f", + " (tryb manewrowy)", + "\nTemperatury:\n silnik: %.2f, olej: %.2f, woda: %.2f%c%.2f", + "Hamulce:\n zespolony: %.2f, pomocniczy: %.2f, nastawa: %s, ladunek: %d\nCisnienie w cylindrach:\n zespolony: %.2f, pomocniczy: %.2f, status: 0x%.2x\nCisnienia w przewodach:\n glowny: %.2f (kapturek: %.2f), zasilajacy: %.2f, kontrolny: %.2f\nCisnienia w zbiornikach:\n pomocniczy: %.2f, glowny: %.2f, sterujacy: %.2f", + " pantograf: %.2f%cZG", + "Sily:\n napedna: %.1f, hamowania: %.1f, tarcie: %.2f%s\nPrzyspieszenia:\n styczne: %.2f, normalne: %.2f (promien: %s)\nPredkosc: %.2f, pokonana odleglosc: %.2f\nPozycja: [%.2f, %.2f, %.2f]" + } + } ); + + auto const lookup = stringmap.find( Global.asLang ); + + locale::strings = ( + lookup != stringmap.end() ? + lookup->second : + stringmap.find( "en" )->second ); +} + std::string label_cab_control( std::string const &Label ) { @@ -26,6 +121,102 @@ label_cab_control( std::string const &Label ) { "" ); } +std::vector strings; + +std::unordered_map m_cabcontrols = { + { "mainctrl:", "master controller" }, + { "scndctrl:", "second controller" }, + { "shuntmodepower:", "shunt mode power" }, + { "dirkey:" , "reverser" }, + { "brakectrl:", "train brake" }, + { "localbrake:", "independent brake" }, + { "manualbrake:", "manual brake" }, + { "alarmchain:", "emergency brake" }, + { "brakeprofile_sw:", "brake acting speed" }, + { "brakeprofileg_sw:", "brake acting speed: cargo" }, + { "brakeprofiler_sw:", "brake acting speed: rapid" }, + { "maxcurrent_sw:", "motor overload relay threshold" }, + { "waterpump_sw:", "water pump" }, + { "waterpumpbreaker_sw:", "water pump breaker" }, + { "waterheater_sw:", "water heater" }, + { "waterheaterbreaker_sw:", "water heater breaker" }, + { "watercircuitslink_sw:", "water circuits link" }, + { "fuelpump_sw:", "fuel pump" }, + { "oilpump_sw:", "oil pump" }, + { "main_off_bt:", "line breaker" }, + { "main_on_bt:", "line breaker" }, + { "security_reset_bt:", "alerter" }, + { "releaser_bt:", "independent brake releaser" }, + { "sand_bt:", "sandbox" }, + { "antislip_bt:", "wheelspin brake" }, + { "horn_bt:", "horn" }, + { "hornlow_bt:", "low tone horn" }, + { "hornhigh_bt:", "high tone horn" }, + { "whistle_bt:", "whistle" }, + { "fuse_bt:", "motor overload relay reset" }, + { "converterfuse_bt:", "converter overload relay reset" }, + { "stlinoff_bt:", "motor connectors" }, + { "door_left_sw:", "left door" }, + { "door_right_sw:", "right door" }, + { "doorlefton_sw:", "left door" }, + { "doorrighton_sw:", "right door" }, + { "doorleftoff_sw:", "left door" }, + { "doorrightoff_sw:", "right door" }, + { "dooralloff_sw:", "all doors" }, + { "departure_signal_bt:", "departure signal" }, + { "upperlight_sw:", "upper headlight" }, + { "leftlight_sw:", "left headlight" }, + { "rightlight_sw:", "right headlight" }, + { "dimheadlights_sw:", "headlights dimmer" }, + { "leftend_sw:", "left marker light" }, + { "rightend_sw:", "right marker light" }, + { "lights_sw:", "light pattern" }, + { "rearupperlight_sw:", "rear upper headlight" }, + { "rearleftlight_sw:", "rear left headlight" }, + { "rearrightlight_sw:", "rear right headlight" }, + { "rearleftend_sw:", "rear left marker light" }, + { "rearrightend_sw:", "rear right marker light" }, + { "compressor_sw:", "compressor" }, + { "compressorlocal_sw:", "local compressor" }, + { "converter_sw:", "converter" }, + { "converterlocal_sw:", "local converter" }, + { "converteroff_sw:", "converter" }, + { "main_sw:", "line breaker" }, + { "radio_sw:", "radio" }, + { "radiochannel_sw:", "radio channel" }, + { "radiochannelprev_sw:", "radio channel" }, + { "radiochannelnext_sw:", "radio channel" }, + { "radiotest_sw:", "radiostop test" }, + { "radiostop_sw:", "radiostop" }, + { "pantfront_sw:", "pantograph A" }, + { "pantrear_sw:", "pantograph B" }, + { "pantfrontoff_sw:", "pantograph A" }, + { "pantrearoff_sw:", "pantograph B" }, + { "pantalloff_sw:", "all pantographs" }, + { "pantselected_sw:", "selected pantograph" }, + { "pantselectedoff_sw:", "selected pantograph" }, + { "pantcompressor_sw:", "pantograph compressor" }, + { "pantcompressorvalve_sw:", "pantograph 3 way valve" }, + { "trainheating_sw:", "heating" }, + { "signalling_sw:", "braking indicator" }, + { "door_signalling_sw:", "door locking" }, + { "nextcurrent_sw:", "current indicator source" }, + { "instrumentlight_sw:", "instrument light" }, + { "cablight_sw:", "interior light" }, + { "cablightdim_sw:", "interior light dimmer" }, + { "battery_sw:", "battery" }, + { "universal0:", "generic" }, + { "universal1:", "generic" }, + { "universal2:", "generic" }, + { "universal3:", "generic" }, + { "universal4:", "generic" }, + { "universal5:", "generic" }, + { "universal6:", "generic" }, + { "universal7:", "generic" }, + { "universal8:", "generic" }, + { "universal9:", "generic" } +}; + } // namespace locale //--------------------------------------------------------------------------- diff --git a/translation.h b/translation.h index dd4ae559..260e0f8f 100644 --- a/translation.h +++ b/translation.h @@ -14,102 +14,51 @@ http://mozilla.org/MPL/2.0/. namespace locale { +enum string { + driver_aid_header, + driver_aid_throttle, + driver_aid_speedlimit, + driver_aid_nextlimit, + driver_aid_grade, + driver_aid_brakes, + driver_aid_pressures, + driver_aid_alerter, + driver_aid_shp, + driver_aid_loadinginprogress, + driver_aid_vehicleahead, + + driver_timetable_header, + driver_timetable_time, + driver_timetable_notimetable, + + driver_transcripts_header, + + driver_pause_header, + driver_pause_resume, + driver_pause_quit, + + debug_vehicle_nameloadstatuscouplers, + debug_vehicle_owned, + debug_vehicle_none, + debug_vehicle_devicespower, + debug_vehicle_radio, + debug_vehicle_oilpressure, + debug_vehicle_controllersenginerevolutions, + debug_vehicle_shuntmode, + debug_vehicle_temperatures, + debug_vehicle_brakespressures, + debug_vehicle_pantograph, + debug_vehicle_forcesaccelerationvelocityposition +}; + +void + init(); std::string label_cab_control( std::string const &Label ); -static std::unordered_map m_cabcontrols = { - { "mainctrl:", "master controller" }, - { "scndctrl:", "second controller" }, - { "shuntmodepower:", "shunt mode power" }, - { "dirkey:" , "reverser" }, - { "brakectrl:", "train brake" }, - { "localbrake:", "independent brake" }, - { "manualbrake:", "manual brake" }, - { "alarmchain:", "emergency brake" }, - { "brakeprofile_sw:", "brake acting speed" }, - { "brakeprofileg_sw:", "brake acting speed: cargo" }, - { "brakeprofiler_sw:", "brake acting speed: rapid" }, - { "maxcurrent_sw:", "motor overload relay threshold" }, - { "waterpump_sw:", "water pump" }, - { "waterpumpbreaker_sw:", "water pump breaker" }, - { "waterheater_sw:", "water heater" }, - { "waterheaterbreaker_sw:", "water heater breaker" }, - { "watercircuitslink_sw:", "water circuits link" }, - { "fuelpump_sw:", "fuel pump" }, - { "oilpump_sw:", "oil pump" }, - { "main_off_bt:", "line breaker" }, - { "main_on_bt:", "line breaker" }, - { "security_reset_bt:", "alerter" }, - { "releaser_bt:", "independent brake releaser" }, - { "sand_bt:", "sandbox" }, - { "antislip_bt:", "wheelspin brake" }, - { "horn_bt:", "horn" }, - { "hornlow_bt:", "low tone horn" }, - { "hornhigh_bt:", "high tone horn" }, - { "whistle_bt:", "whistle" }, - { "fuse_bt:", "motor overload relay reset" }, - { "converterfuse_bt:", "converter overload relay reset" }, - { "stlinoff_bt:", "motor connectors" }, - { "door_left_sw:", "left door" }, - { "door_right_sw:", "right door" }, - { "doorlefton_sw:", "left door" }, - { "doorrighton_sw:", "right door" }, - { "doorleftoff_sw:", "left door" }, - { "doorrightoff_sw:", "right door" }, - { "dooralloff_sw:", "all doors" }, - { "departure_signal_bt:", "departure signal" }, - { "upperlight_sw:", "upper headlight" }, - { "leftlight_sw:", "left headlight" }, - { "rightlight_sw:", "right headlight" }, - { "dimheadlights_sw:", "headlights dimmer" }, - { "leftend_sw:", "left marker light" }, - { "rightend_sw:", "right marker light" }, - { "lights_sw:", "light pattern" }, - { "rearupperlight_sw:", "rear upper headlight" }, - { "rearleftlight_sw:", "rear left headlight" }, - { "rearrightlight_sw:", "rear right headlight" }, - { "rearleftend_sw:", "rear left marker light" }, - { "rearrightend_sw:", "rear right marker light" }, - { "compressor_sw:", "compressor" }, - { "compressorlocal_sw:", "local compressor" }, - { "converter_sw:", "converter" }, - { "converterlocal_sw:", "local converter" }, - { "converteroff_sw:", "converter" }, - { "main_sw:", "line breaker" }, - { "radio_sw:", "radio" }, - { "radiochannel_sw:", "radio channel" }, - { "radiochannelprev_sw:", "radio channel" }, - { "radiochannelnext_sw:", "radio channel" }, - { "radiotest_sw:", "radiostop test" }, - { "radiostop_sw:", "radiostop" }, - { "pantfront_sw:", "pantograph A" }, - { "pantrear_sw:", "pantograph B" }, - { "pantfrontoff_sw:", "pantograph A" }, - { "pantrearoff_sw:", "pantograph B" }, - { "pantalloff_sw:", "all pantographs" }, - { "pantselected_sw:", "selected pantograph" }, - { "pantselectedoff_sw:", "selected pantograph" }, - { "pantcompressor_sw:", "pantograph compressor" }, - { "pantcompressorvalve_sw:", "pantograph 3 way valve" }, - { "trainheating_sw:", "heating" }, - { "signalling_sw:", "braking indicator" }, - { "door_signalling_sw:", "door locking" }, - { "nextcurrent_sw:", "current indicator source" }, - { "instrumentlight_sw:", "instrument light" }, - { "cablight_sw:", "interior light" }, - { "cablightdim_sw:", "interior light dimmer" }, - { "battery_sw:", "battery" }, - { "universal0:", "generic" }, - { "universal1:", "generic" }, - { "universal2:", "generic" }, - { "universal3:", "generic" }, - { "universal4:", "generic" }, - { "universal5:", "generic" }, - { "universal6:", "generic" }, - { "universal7:", "generic" }, - { "universal8:", "generic" }, - { "universal9:", "generic" } -}; +extern std::vector strings; + +extern std::unordered_map m_cabcontrols; } diff --git a/uilayer.cpp b/uilayer.cpp index 38495317..8c0e4f28 100644 --- a/uilayer.cpp +++ b/uilayer.cpp @@ -27,8 +27,8 @@ GLint ui_layer::m_textureunit { GL_TEXTURE0 }; bool ui_layer::m_cursorvisible { true }; -ui_panel::ui_panel( std::string const Name, bool const Isopen ) - : name( Name ), is_open( Isopen ) +ui_panel::ui_panel( std::string const Identifier, bool const Isopen ) + : identifier( Identifier ), is_open( Isopen ) {} void @@ -48,7 +48,12 @@ ui_panel::render() { if( size_min.x > 0 ) { ImGui::SetNextWindowSizeConstraints( ImVec2( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) ); } - if( true == ImGui::Begin( name.c_str(), &is_open, flags ) ) { + auto const panelname { ( + name.empty() ? + identifier : + name ) + + "###" + identifier }; + if( true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) { for( auto const &line : text_lines ) { ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() ); } diff --git a/uilayer.h b/uilayer.h index 038e3f5a..d22461b8 100644 --- a/uilayer.h +++ b/uilayer.h @@ -18,7 +18,7 @@ class ui_panel { public: // constructor - ui_panel( std::string const Name, bool const Isopen ); + ui_panel( std::string const Identifier, bool const Isopen ); // methods virtual void update() {}; virtual void render(); @@ -34,6 +34,7 @@ public: {} }; // members + std::string name; bool is_open; glm::ivec2 size { -1, -1 }; glm::ivec2 size_min { -1, -1 }; @@ -42,7 +43,7 @@ public: protected: // members - std::string name; + std::string identifier; }; class ui_layer {