16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-23 12:09:18 +02:00

Merge branch 'master' into master

This commit is contained in:
Ryba04
2025-09-13 19:46:26 +02:00
committed by GitHub
36 changed files with 767 additions and 678 deletions

View File

@@ -433,12 +433,7 @@ void TAnimModel::RaAnimate( unsigned int const Framestamp ) {
auto &timer { m_lighttimers[ idx ] }; auto &timer { m_lighttimers[ idx ] };
if( ( modeintegral < ls_Blink ) && ( modefractional < 0.01f ) ) { if( ( modeintegral < ls_Blink ) && ( modefractional < 0.01f ) ) {
// simple flip modes // simple flip modes
auto const transitiontime { ( auto const transitiontime { ( m_transition ? std::min( 0.65f, std::min( fOnTime, fOffTime ) * 0.45f ) : 0.01f ) };
m_transition ?
std::min(
1.f,
std::min( fOnTime, fOffTime ) * 0.9f ) :
0.01f ) };
switch( mode ) { switch( mode ) {
case ls_Off: { case ls_Off: {
@@ -469,14 +464,9 @@ void TAnimModel::RaAnimate( unsigned int const Framestamp ) {
( mode == ls_Off ) ? ontime : ( mode == ls_Off ) ? ontime :
( mode == ls_On ) ? ( fOnTime + fOffTime ) - ontime : ( mode == ls_On ) ? ( fOnTime + fOffTime ) - ontime :
fOffTime ) }; // fallback fOffTime ) }; // fallback
auto const transitiontime { ( auto const transitiontime { ( m_transition ? std::min(0.65f, std::min( ontime, offtime ) * 0.45f ) : 0.01f ) };
m_transition ?
std::min(
1.f,
std::min( ontime, offtime ) * 0.9f ) :
0.01f ) };
timer = clamp_circular<float>( timer + timedelta * ( lsLights[ idx ] > 0.f ? 1.f : -1.f ), ontime + offtime ); timer = fmod(timer + timedelta * ( lsLights[ idx ] > 0.f ? 1.f : -1.f ), ontime + offtime);
// set opacity depending on blink stage // set opacity depending on blink stage
if( timer < ontime ) { if( timer < ontime ) {
// blink on // blink on
@@ -500,50 +490,14 @@ void TAnimModel::RaAnimate( unsigned int const Framestamp ) {
// aktualizujemy submodele w zaleznosci od aktualnej porty roku // aktualizujemy submodele w zaleznosci od aktualnej porty roku
void TAnimModel::on_season_update() { void TAnimModel::on_season_update() {
if (Global.Season == "winter:") // pokazujemy wariant zimowy if (this->sm_winter_variant != nullptr) // pokazujemy wariant zimowy
{ this->sm_winter_variant->SetVisibilityLevel(Global.Season == "winter:" ? 1 : 0, true, false);
if (this->sm_winter_variant != nullptr) if (this->sm_spring_variant != nullptr) // pokazujemy wariant wiosenny
this->sm_winter_variant->SetVisibilityLevel(1.f, true, false); this->sm_spring_variant->SetVisibilityLevel(Global.Season == "spring:" ? 1 : 0, true, false);
if (this->sm_spring_variant != nullptr) if (this->sm_summer_variant != nullptr) // pokazujemy wariant letni
this->sm_spring_variant->SetVisibilityLevel(0.f, true, false); this->sm_summer_variant->SetVisibilityLevel(Global.Season == "summer:" ? 1 : 0, true, false);
if (this->sm_summer_variant != nullptr) if (this->sm_autumn_variant != nullptr) // pokazujemy wariant jesienny
this->sm_summer_variant->SetVisibilityLevel(0.f, true, false); this->sm_autumn_variant->SetVisibilityLevel(Global.Season == "autumn:" ? 1 : 0, true, false);
if (this->sm_autumn_variant != nullptr)
this->sm_autumn_variant->SetVisibilityLevel(0.f, true, false);
}
else if (Global.Season == "spring:") // pokazujemy wariant wiosenny
{
if (this->sm_winter_variant != nullptr)
this->sm_winter_variant->SetVisibilityLevel(0.f, true, false);
if (this->sm_spring_variant != nullptr)
this->sm_spring_variant->SetVisibilityLevel(1.f, true, false);
if (this->sm_summer_variant != nullptr)
this->sm_summer_variant->SetVisibilityLevel(0.f, true, false);
if (this->sm_autumn_variant != nullptr)
this->sm_autumn_variant->SetVisibilityLevel(0.f, true, false);
}
else if (Global.Season == "summer:") // pokazujemy wariant letni
{
if (this->sm_winter_variant != nullptr)
this->sm_winter_variant->SetVisibilityLevel(0.f, true, false);
if (this->sm_spring_variant != nullptr)
this->sm_spring_variant->SetVisibilityLevel(0.f, true, false);
if (this->sm_summer_variant != nullptr)
this->sm_summer_variant->SetVisibilityLevel(1.f, true, false);
if (this->sm_autumn_variant != nullptr)
this->sm_autumn_variant->SetVisibilityLevel(0.f, true, false);
}
else if (Global.Season == "autumn:") // pokazujemy wariant jesienny
{
if (this->sm_winter_variant != nullptr)
this->sm_winter_variant->SetVisibilityLevel(0.f, true, false);
if (this->sm_spring_variant != nullptr)
this->sm_spring_variant->SetVisibilityLevel(0.f, true, false);
if (this->sm_summer_variant != nullptr)
this->sm_summer_variant->SetVisibilityLevel(0.f, true, false);
if (this->sm_autumn_variant != nullptr)
this->sm_autumn_variant->SetVisibilityLevel(1.f, true, false);
}
} }
void TAnimModel::RaPrepare() void TAnimModel::RaPrepare()

View File

@@ -159,6 +159,7 @@ set(SOURCES
"editoruilayer.cpp" "editoruilayer.cpp"
"editoruipanels.cpp" "editoruipanels.cpp"
"scenarioloadermode.cpp" "scenarioloadermode.cpp"
"scenarioloaderuilayer.cpp"
"scenenodegroups.cpp" "scenenodegroups.cpp"
"simulationenvironment.cpp" "simulationenvironment.cpp"
"simulationstateserializer.cpp" "simulationstateserializer.cpp"

View File

@@ -236,7 +236,7 @@ struct global_settings {
std::string asVersion; // z opisem std::string asVersion; // z opisem
motiontelemetry::conf_t motiontelemetry_conf; motiontelemetry::conf_t motiontelemetry_conf;
std::string screenshot_dir; std::string screenshot_dir;
bool loading_log = true; bool loading_log = false;
bool dds_upper_origin = false; bool dds_upper_origin = false;
bool captureonstart = true; bool captureonstart = true;
bool render_cab = true; bool render_cab = true;

View File

@@ -609,6 +609,13 @@ struct TDEScheme
double Umax = 0.0; /*napiecie maksymalne*/ double Umax = 0.0; /*napiecie maksymalne*/
double Imax = 0.0; /*prad maksymalny*/ double Imax = 0.0; /*prad maksymalny*/
}; };
typedef TDEScheme TDESchemeTable[33]; /*tablica WWList dla silnikow spalinowych*/
struct TFFScheme
{
double v = 0.0; // parametr wejsciowy
double freq = 0.0; // wyjscie: czestotliwosc falownika
};
typedef TFFScheme TFFSchemeTable[33];
struct TWiperScheme struct TWiperScheme
{ {
@@ -619,8 +626,6 @@ struct TWiperScheme
}; };
typedef TWiperScheme TWiperSchemeTable[16]; typedef TWiperScheme TWiperSchemeTable[16];
typedef TDEScheme TDESchemeTable[33]; /*tablica rezystorow rozr.*/
struct TShuntScheme struct TShuntScheme
{ {
double Umin = 0.0; double Umin = 0.0;
@@ -1376,6 +1381,10 @@ class TMoverParameters
bool Flat = false; bool Flat = false;
double Vhyp = 1.0; double Vhyp = 1.0;
TDESchemeTable DElist; TDESchemeTable DElist;
TFFSchemeTable FFlist;
int FFListSize = 0;
TFFSchemeTable FFEDlist;
int FFEDListSize = 0;
TWiperSchemeTable WiperList; TWiperSchemeTable WiperList;
int WiperListSize; int WiperListSize;
int modernWpierListSize; int modernWpierListSize;
@@ -2081,6 +2090,7 @@ private:
void LoadFIZ_UCList(std::string const &Input); void LoadFIZ_UCList(std::string const &Input);
void LoadFIZ_DList( std::string const &Input ); void LoadFIZ_DList( std::string const &Input );
void LoadFIZ_FFList( std::string const &Input ); void LoadFIZ_FFList( std::string const &Input );
void LoadFIZ_FFEDList( std::string const &Input );
void LoadFIZ_WiperList(std::string const &Input); void LoadFIZ_WiperList(std::string const &Input);
void LoadFIZ_LightsList( std::string const &Input ); void LoadFIZ_LightsList( std::string const &Input );
void LoadFIZ_DimmerList(std::string const &Input); void LoadFIZ_DimmerList(std::string const &Input);
@@ -2103,6 +2113,7 @@ private:
bool readHTCList(std::string const &line); bool readHTCList(std::string const &line);
bool readPmaxList(std::string const &line); bool readPmaxList(std::string const &line);
bool readFFList( std::string const &line ); bool readFFList( std::string const &line );
bool readFFEDList( std::string const &line );
bool readWWList( std::string const &line ); bool readWWList( std::string const &line );
bool readWiperList( std::string const &line ); bool readWiperList( std::string const &line );
bool readDimmerList(std::string const &line); bool readDimmerList(std::string const &line);

View File

@@ -6432,21 +6432,24 @@ double TMoverParameters::TractionForce( double dt ) {
EnginePower = abs(eimv[eimv_Ic] * eimv[eimv_U] * NPoweredAxles) / 1000; EnginePower = abs(eimv[eimv_Ic] * eimv[eimv_U] * NPoweredAxles) / 1000;
// power inverters // power inverters
auto const tmpV { std::abs( eimv[ eimv_fp ] ) }; auto const tmpV { std::abs( eimv[ eimv_fp ] ) };
auto const useFFEDList = FFEDListSize > 0 && DynamicBrakeFlag;
auto const list = useFFEDList ? FFEDlist : FFlist;
auto const listSize = useFFEDList ? FFEDListSize : FFListSize;
if( ( RlistSize > 0 ) if( ( listSize > 0 )
&& ( ( std::abs( eimv[ eimv_If ] ) > 1.0 ) && ( ( std::abs( eimv[ eimv_If ] ) > 1.0 )
&& ( tmpV > 0.0001 ) ) ) { && ( tmpV > 0.0001 ) ) ) {
int i = 0; int i = 0;
while( ( i < RlistSize - 1 ) while( ( i < listSize - 1 )
&& ( DElist[ i + 1 ].RPM < tmpV ) ) { && ( list[ i + 1 ].v < tmpV ) ) {
++i; ++i;
} }
InverterFrequency = InverterFrequency =
( tmpV - DElist[ i ].RPM ) ( tmpV - list[ i ].v )
/ std::max( 1.0, ( DElist[ i + 1 ].RPM - DElist[ i ].RPM ) ) / std::max( 1.0, ( list[ i + 1 ].v - list[ i ].v ) )
* ( DElist[ i + 1 ].GenPower - DElist[ i ].GenPower ) * ( list[ i + 1 ].freq - list[ i ].freq )
+ DElist[ i ].GenPower; + list[ i ].freq;
} }
else { else {
InverterFrequency = 0.0; InverterFrequency = 0.0;
@@ -8927,7 +8930,7 @@ bool startBPT;
bool startMPT, startMPT0; bool startMPT, startMPT0;
bool startRLIST, startUCLIST; bool startRLIST, startUCLIST;
bool startDIZELMOMENTUMLIST, startDIZELV2NMAXLIST, startHYDROTCLIST, startPMAXLIST; bool startDIZELMOMENTUMLIST, startDIZELV2NMAXLIST, startHYDROTCLIST, startPMAXLIST;
bool startDLIST, startFFLIST, startWWLIST, startWiperList, startDimmerList; bool startDLIST, startFFLIST, startWWLIST, startWiperList, startDimmerList, startFFEDLIST;
bool startLIGHTSLIST; bool startLIGHTSLIST;
bool startCOMPRESSORLIST; bool startCOMPRESSORLIST;
int LISTLINE; int LISTLINE;
@@ -9268,13 +9271,32 @@ bool TMoverParameters::readFFList( std::string const &line ) {
return false; return false;
} }
int idx = LISTLINE++; int idx = LISTLINE++;
if( idx >= sizeof( DElist ) / sizeof( TDEScheme ) ) { if( idx >= sizeof( FFlist ) / sizeof( TFFScheme ) ) {
WriteLog( "Read FList: number of entries exceeded capacity of the data table" ); WriteLog( "Read FList: number of entries exceeded capacity of the data table" );
return false; return false;
} }
parser parser
>> DElist[ idx ].RPM >> FFlist[ idx ].v
>> DElist[ idx ].GenPower; >> FFlist[ idx ].freq;
return true;
}
bool TMoverParameters::readFFEDList( std::string const &line ) {
cParser parser( line );
if( false == parser.getTokens( 2, false ) ) {
WriteLog( "Read FList: arguments missing in line " + std::to_string( LISTLINE + 1 ) );
return false;
}
int idx = LISTLINE++;
if( idx >= sizeof( FFEDlist ) / sizeof( TFFScheme ) ) {
WriteLog( "Read FList: number of entries exceeded capacity of the data table" );
return false;
}
parser
>> FFEDlist[ idx ].v
>> FFEDlist[ idx ].freq;
return true; return true;
} }
@@ -9496,6 +9518,7 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
startHYDROTCLIST = false; startHYDROTCLIST = false;
startPMAXLIST = false; startPMAXLIST = false;
startFFLIST = false; startFFLIST = false;
startFFEDLIST = false;
startWWLIST = false; startWWLIST = false;
startWiperList = false; startWiperList = false;
startDimmerList = false; startDimmerList = false;
@@ -9597,6 +9620,7 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
if( issection( "endff", inputline ) ) { if( issection( "endff", inputline ) ) {
startBPT = false; startBPT = false;
startFFLIST = false; startFFLIST = false;
startFFEDLIST = false;
continue; continue;
} }
if (issection("endwl", inputline)) if (issection("endwl", inputline))
@@ -9900,6 +9924,13 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
continue; continue;
} }
if( issection( "ffBrakeList:", inputline ) ) {
startBPT = false;
startFFEDLIST = true; LISTLINE = 0;
LoadFIZ_FFEDList( inputline );
continue;
}
if( issection( "WWList:", inputline ) ) if( issection( "WWList:", inputline ) )
{ {
startBPT = false; startBPT = false;
@@ -9992,6 +10023,10 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
readFFList( inputline ); readFFList( inputline );
continue; continue;
} }
if( true == startFFEDLIST ) {
readFFEDList( inputline );
continue;
}
if( true == startWWLIST ) { if( true == startWWLIST ) {
readWWList( inputline ); readWWList( inputline );
continue; continue;
@@ -11354,8 +11389,11 @@ void TMoverParameters::LoadFIZ_DList( std::string const &Input ) {
} }
void TMoverParameters::LoadFIZ_FFList( std::string const &Input ) { void TMoverParameters::LoadFIZ_FFList( std::string const &Input ) {
extract_value( FFListSize, "Size", Input, "" );
}
extract_value( RlistSize, "Size", Input, "" ); void TMoverParameters::LoadFIZ_FFEDList( std::string const &Input ) {
extract_value( FFEDListSize, "Size", Input, "" );
} }
void TMoverParameters::LoadFIZ_WiperList(std::string const &Input) void TMoverParameters::LoadFIZ_WiperList(std::string const &Input)

View File

@@ -2366,6 +2366,19 @@ TTrack::export_as_text_( std::ostream &Output ) const {
<< "\n"; << "\n";
} }
// Returns the tooltip of this Track, which may contain a list of isolations if the track belongs to any.
std::string TTrack::tooltip() const
{
std::string tooltip = this->name();
if (!Isolated.empty())
{
tooltip += "\nIsolated:";
for (const auto isolation : Isolated)
tooltip += " " + isolation->asName;
}
return tooltip;
}
// locates specified profile in the profile database, potentially loading it from a file // locates specified profile in the profile database, potentially loading it from a file
// returns: pair <profile name, profile handle> // returns: pair <profile name, profile handle>
std::pair<std::string, int> std::pair<std::string, int>

View File

@@ -316,6 +316,7 @@ public:
void ConnectionsLog(); void ConnectionsLog();
bool DoubleSlip() const; bool DoubleSlip() const;
static void fetch_default_profiles(); static void fetch_default_profiles();
std::string tooltip() const override;
private: private:
// types // types

View File

@@ -81,6 +81,7 @@ void framebuffer_resize_callback( GLFWwindow *, int w, int h ) {
void window_resize_callback( GLFWwindow *, int w, int h ) { void window_resize_callback( GLFWwindow *, int w, int h ) {
Global.window_size = glm::ivec2(w, h); Global.window_size = glm::ivec2(w, h);
Application.on_window_resize(w, h);
} }
void cursor_pos_callback( GLFWwindow *window, double x, double y ) { void cursor_pos_callback( GLFWwindow *window, double x, double y ) {
@@ -662,19 +663,19 @@ eu07_application::pop_mode() {
} }
bool bool
eu07_application::push_mode( eu07_application::mode const Mode ) { eu07_application::push_mode( mode const Mode ) {
if( Mode >= mode::count_ ) if( Mode >= count_ )
return false; return false;
if (!m_modes[Mode]) { if (!m_modes[Mode]) {
if (Mode == mode::launcher) if (Mode == launcher)
m_modes[Mode] = std::make_shared<launcher_mode>(); m_modes[Mode] = std::make_shared<launcher_mode>();
if (Mode == mode::scenarioloader) if (Mode == scenarioloader)
m_modes[Mode] = std::make_shared<scenarioloader_mode>(); m_modes[Mode] = std::make_shared<scenarioloader_mode>();
if (Mode == mode::driver) if (Mode == driver)
m_modes[Mode] = std::make_shared<driver_mode>(); m_modes[Mode] = std::make_shared<driver_mode>();
if (Mode == mode::editor) if (Mode == editor)
m_modes[Mode] = std::make_shared<editor_mode>(); m_modes[Mode] = std::make_shared<editor_mode>();
if (!m_modes[Mode]->init()) if (!m_modes[Mode]->init())
@@ -740,6 +741,13 @@ eu07_application::on_key( int const Key, int const Scancode, int const Action, i
if( m_modestack.empty() ) { return; } if( m_modestack.empty() ) { return; }
if (Key == GLFW_KEY_LEFT_SHIFT || Key == GLFW_KEY_RIGHT_SHIFT)
Global.shiftState = Action == GLFW_PRESS;
if (Key == GLFW_KEY_LEFT_CONTROL || Key == GLFW_KEY_RIGHT_CONTROL)
Global.ctrlState = Action == GLFW_PRESS;
if (Key == GLFW_KEY_LEFT_ALT || Key == GLFW_KEY_RIGHT_ALT)
Global.altState = Action == GLFW_PRESS;
m_modes[ m_modestack.top() ]->on_key( Key, Scancode, Action, Mods ); m_modes[ m_modestack.top() ]->on_key( Key, Scancode, Action, Mods );
} }
@@ -779,12 +787,20 @@ void eu07_application::on_char(unsigned int c) {
} }
void eu07_application::on_focus_change(bool focus) { void eu07_application::on_focus_change(bool focus) {
if( Global.bInactivePause && !m_network->client) {// jeśli ma być pauzowanie okna w tle if( Global.bInactivePause && m_network.has_value() && !m_network->client) {// jeśli ma być pauzowanie okna w tle
command_relay relay; command_relay relay;
relay.post(user_command::focuspauseset, focus ? 1.0 : 0.0, 0.0, GLFW_PRESS, 0); relay.post(user_command::focuspauseset, focus ? 1.0 : 0.0, 0.0, GLFW_PRESS, 0);
} }
} }
void eu07_application::on_window_resize(int w, int h)
{
if (m_modestack.empty())
return;
m_modes[m_modestack.top()]->on_window_resize(w, h);
}
GLFWwindow * GLFWwindow *
eu07_application::window(int const Windowindex, bool visible, int width, int height, GLFWmonitor *monitor, bool keep_ownership , bool share_ctx) { eu07_application::window(int const Windowindex, bool visible, int width, int height, GLFWmonitor *monitor, bool keep_ownership , bool share_ctx) {

View File

@@ -70,18 +70,13 @@ public:
set_cursor_pos( double const Horizontal, double const Vertical ); set_cursor_pos( double const Horizontal, double const Vertical );
void queue_screenshot(); void queue_screenshot();
// input handlers // input handlers
void void on_key( int const Key, int const Scancode, int const Action, int const Mods );
on_key( int const Key, int const Scancode, int const Action, int const Mods ); void on_char( unsigned int const Char );
void void on_cursor_pos( double const Horizontal, double const Vertical );
on_char( unsigned int const Char ); void on_mouse_button( int const Button, int const Action, int const Mods );
void void on_scroll( double const Xoffset, double const Yoffset );
on_cursor_pos( double const Horizontal, double const Vertical ); void on_focus_change(bool focus);
void void on_window_resize(int w, int h);
on_mouse_button( int const Button, int const Action, int const Mods );
void
on_scroll( double const Xoffset, double const Yoffset );
void
on_focus_change(bool focus);
// gives access to specified window, creates a new window if index == -1 // gives access to specified window, creates a new window if index == -1
GLFWwindow * GLFWwindow *
window( int const Windowindex = 0, bool visible = false, int width = 1, int height = 1, GLFWmonitor *monitor = nullptr, bool keep_ownership = true, bool share_ctx = true ); window( int const Windowindex = 0, bool visible = false, int width = 1, int height = 1, GLFWmonitor *monitor = nullptr, bool keep_ownership = true, bool share_ctx = true );

View File

@@ -17,65 +17,41 @@ class application_mode {
public: public:
// destructor // destructor
virtual virtual ~application_mode() = default;
~application_mode() = default;
// methods; // methods;
// initializes internal data structures of the mode. returns: true on success, false otherwise // initializes internal data structures of the mode. returns: true on success, false otherwise
virtual virtual bool init() = 0;
bool
init() = 0;
// mode-specific update of simulation data. returns: false on error, true otherwise // mode-specific update of simulation data. returns: false on error, true otherwise
virtual virtual bool update() = 0;
bool
update() = 0;
// draws mode-specific user interface // draws mode-specific user interface
inline inline
void void render_ui() {
render_ui() {
if( m_userinterface != nullptr ) { if( m_userinterface != nullptr ) {
m_userinterface->render(); } } m_userinterface->render(); } }
inline inline
void void begin_ui_frame() {
begin_ui_frame() {
if( m_userinterface != nullptr ) { if( m_userinterface != nullptr ) {
m_userinterface->begin_ui_frame(); } } m_userinterface->begin_ui_frame(); } }
inline inline
void void set_progress( float const Progress = 0.f, float const Subtaskprogress = 0.f ) {
set_progress( float const Progress = 0.f, float const Subtaskprogress = 0.f ) {
if( m_userinterface != nullptr ) { if( m_userinterface != nullptr ) {
m_userinterface->set_progress( Progress, Subtaskprogress ); } } m_userinterface->set_progress( Progress, Subtaskprogress ); } }
inline inline
void void set_tooltip( std::string const &Tooltip ) {
set_tooltip( std::string const &Tooltip ) {
if( m_userinterface != nullptr ) { if( m_userinterface != nullptr ) {
m_userinterface->set_tooltip( Tooltip ); } } m_userinterface->set_tooltip( Tooltip ); } }
// maintenance method, called when the mode is activated // maintenance method, called when the mode is activated
virtual virtual void enter() = 0;
void
enter() = 0;
// maintenance method, called when the mode is deactivated // maintenance method, called when the mode is deactivated
virtual virtual void exit() = 0;
void
exit() = 0;
// input handlers // input handlers
virtual virtual void on_key( int Key, int Scancode, int Action, int Mods ) = 0;
void virtual void on_cursor_pos( double X, double Y ) = 0;
on_key( int const Key, int const Scancode, int const Action, int const Mods ) = 0; virtual void on_mouse_button( int Button, int Action, int Mods ) = 0;
virtual virtual void on_scroll( double Xoffset, double Yoffset ) = 0;
void virtual void on_window_resize( int w, int h ) = 0;
on_cursor_pos( double const X, double const Y ) = 0; virtual void on_event_poll() = 0;
virtual virtual bool is_command_processor() const = 0;
void
on_mouse_button( int const Button, int const Action, int const Mods ) = 0;
virtual
void
on_scroll( double const Xoffset, double const Yoffset ) = 0;
virtual
void
on_event_poll() = 0;
virtual
bool
is_command_processor() const = 0;
protected: protected:
// members // members

View File

@@ -341,12 +341,10 @@ driver_mode::update() {
set_tooltip( ( cabcontrol ? cabcontrol->pName : "" ) ); set_tooltip( ( cabcontrol ? cabcontrol->pName : "" ) );
} }
} }
if( ( true == Global.ControlPicking ) && ( true == FreeFlyModeFlag ) && ( true == DebugModeFlag ) ) { if( Global.ControlPicking && FreeFlyModeFlag && DebugModeFlag ) {
auto const scenerynode = GfxRenderer->Pick_Node(); const auto sceneryNode = GfxRenderer->Pick_Node();
set_tooltip( const std::string content = sceneryNode ? sceneryNode->tooltip() : "";
( scenerynode ? set_tooltip(content);
scenerynode->name() :
"" ) );
} }
runonce = true; runonce = true;
@@ -433,10 +431,6 @@ driver_mode::exit() {
void void
driver_mode::on_key( int const Key, int const Scancode, int const Action, int const Mods ) { driver_mode::on_key( int const Key, int const Scancode, int const Action, int const Mods ) {
Global.shiftState = ( Mods & GLFW_MOD_SHIFT ) ? true : false;
Global.ctrlState = ( Mods & GLFW_MOD_CONTROL ) ? true : false;
Global.altState = ( Mods & GLFW_MOD_ALT ) ? true : false;
bool anyModifier = Mods & (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL | GLFW_MOD_ALT); bool anyModifier = Mods & (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL | GLFW_MOD_ALT);
// give the ui first shot at the input processing... // give the ui first shot at the input processing...

View File

@@ -32,30 +32,21 @@ public:
// methods // methods
// initializes internal data structures of the mode. returns: true on success, false otherwise // initializes internal data structures of the mode. returns: true on success, false otherwise
bool bool init() override;
init() override;
// mode-specific update of simulation data. returns: false on error, true otherwise // mode-specific update of simulation data. returns: false on error, true otherwise
bool bool update() override;
update() override;
// maintenance method, called when the mode is activated // maintenance method, called when the mode is activated
void void enter() override;
enter() override;
// maintenance method, called when the mode is deactivated // maintenance method, called when the mode is deactivated
void void exit() override;
exit() override;
// input handlers // input handlers
void void on_key( int Key, int Scancode, int Action, int Mods ) override;
on_key( int const Key, int const Scancode, int const Action, int const Mods ) override; void on_cursor_pos( double Horizontal, double Vertical ) override;
void void on_mouse_button( int Button, int Action, int Mods ) override;
on_cursor_pos( double const Horizontal, double const Vertical ) override; void on_scroll( double Xoffset, double Yoffset ) override;
void void on_window_resize( int w, int h ) override { ; }
on_mouse_button( int const Button, int const Action, int const Mods ) override; void on_event_poll() override;
void bool is_command_processor() const override;
on_scroll( double const Xoffset, double const Yoffset ) override;
void
on_event_poll() override;
bool
is_command_processor() const override;
private: private:
// types // types

View File

@@ -155,10 +155,6 @@ editor_mode::exit() {
void void
editor_mode::on_key( int const Key, int const Scancode, int const Action, int const Mods ) { editor_mode::on_key( int const Key, int const Scancode, int const Action, int const Mods ) {
Global.shiftState = ( Mods & GLFW_MOD_SHIFT ) ? true : false;
Global.ctrlState = ( Mods & GLFW_MOD_CONTROL ) ? true : false;
Global.altState = ( Mods & GLFW_MOD_ALT ) ? true : false;
bool anyModifier = Mods & (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL | GLFW_MOD_ALT); bool anyModifier = Mods & (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL | GLFW_MOD_ALT);
// give the ui first shot at the input processing... // give the ui first shot at the input processing...

View File

@@ -23,30 +23,21 @@ public:
editor_mode(); editor_mode();
// methods // methods
// initializes internal data structures of the mode. returns: true on success, false otherwise // initializes internal data structures of the mode. returns: true on success, false otherwise
bool bool init() override;
init() override;
// mode-specific update of simulation data. returns: false on error, true otherwise // mode-specific update of simulation data. returns: false on error, true otherwise
bool bool update() override;
update() override;
// maintenance method, called when the mode is activated // maintenance method, called when the mode is activated
void void enter() override;
enter() override;
// maintenance method, called when the mode is deactivated // maintenance method, called when the mode is deactivated
void void exit() override;
exit() override;
// input handlers // input handlers
void void on_key( int Key, int Scancode, int Action, int Mods ) override;
on_key( int const Key, int const Scancode, int const Action, int const Mods ) override; void on_cursor_pos( double Horizontal, double Vertical ) override;
void void on_mouse_button( int Button, int Action, int Mods ) override;
on_cursor_pos( double const Horizontal, double const Vertical ) override; void on_scroll( double const Xoffset, double const Yoffset ) override { ; }
void void on_window_resize( int w, int h ) override { ; }
on_mouse_button( int const Button, int const Action, int const Mods ) override; void on_event_poll() override;
void bool is_command_processor() const override;
on_scroll( double const Xoffset, double const Yoffset ) override { ; }
void
on_event_poll() override;
bool
is_command_processor() const override;
private: private:
// types // types

View File

@@ -30,14 +30,10 @@ editor_ui::update() {
set_tooltip( "" ); set_tooltip( "" );
if( ( true == Global.ControlPicking ) if( Global.ControlPicking && DebugModeFlag ) {
&& ( true == DebugModeFlag ) ) { const auto sceneryNode = GfxRenderer->Pick_Node();
const std::string content = sceneryNode ? sceneryNode->tooltip() : "";
auto const scenerynode = GfxRenderer->Pick_Node(); set_tooltip(content);
set_tooltip(
( scenerynode ?
scenerynode->name() :
"" ) );
} }
ui_layer::update(); ui_layer::update();

View File

@@ -36,14 +36,8 @@ bool ui::keymapper_panel::key(int key)
return true; return true;
} }
void ui::keymapper_panel::render() void ui::keymapper_panel::render_contents()
{ {
if (!is_open)
return;
auto const panelname{(title.empty() ? m_name : title) + "###" + m_name};
if (ImGui::Begin(panelname.c_str(), &is_open)) {
if (ImGui::Button(STR_C("Load"))) if (ImGui::Button(STR_C("Load")))
keyboard.init(); keyboard.init();
@@ -99,6 +93,3 @@ void ui::keymapper_panel::render()
ImGui::PopStyleColor(); ImGui::PopStyleColor();
} }
} }
ImGui::End();
}

View File

@@ -10,12 +10,12 @@ class keymapper_panel : public ui_panel
public: public:
keymapper_panel(); keymapper_panel();
void render() override; void render_contents() override;
bool key(int key); bool key(int key);
private: private:
driverkeyboard_input keyboard; driverkeyboard_input keyboard;
user_command bind_active = user_command::none; user_command bind_active = user_command::none;
const std::string panelname = (title.empty() ? m_name : title) + "###" + m_name;
}; };
} // namespace ui } // namespace ui

View File

@@ -23,9 +23,7 @@ bool launcher_mode::update()
void launcher_mode::enter() void launcher_mode::enter()
{ {
Application.set_cursor( GLFW_CURSOR_NORMAL ); Application.set_cursor( GLFW_CURSOR_NORMAL );
simulation::is_ready = false; simulation::is_ready = false;
Application.set_title(Global.AppName); Application.set_title(Global.AppName);
} }
@@ -36,7 +34,10 @@ void launcher_mode::exit()
void launcher_mode::on_key(const int Key, const int Scancode, const int Action, const int Mods) void launcher_mode::on_key(const int Key, const int Scancode, const int Action, const int Mods)
{ {
Global.shiftState = ( Mods & GLFW_MOD_SHIFT ) ? true : false;
Global.ctrlState = ( Mods & GLFW_MOD_CONTROL ) ? true : false;
m_userinterface->on_key(Key, Action); m_userinterface->on_key(Key, Action);
} }
void launcher_mode::on_window_resize(const int w, const int h)
{
m_userinterface->on_window_resize(w, h);
}

View File

@@ -18,28 +18,19 @@ public:
launcher_mode(); launcher_mode();
// methods // methods
// initializes internal data structures of the mode. returns: true on success, false otherwise // initializes internal data structures of the mode. returns: true on success, false otherwise
bool bool init() override;
init() override;
// mode-specific update of simulation data. returns: false on error, true otherwise // mode-specific update of simulation data. returns: false on error, true otherwise
bool bool update() override;
update() override;
// maintenance method, called when the mode is activated // maintenance method, called when the mode is activated
void void enter() override;
enter() override;
// maintenance method, called when the mode is deactivated // maintenance method, called when the mode is deactivated
void void exit() override;
exit() override;
// input handlers // input handlers
void void on_key( int Key, int Scancode, int Action, int Mods ) override;
on_key( int const Key, int const Scancode, int const Action, int const Mods ); void on_cursor_pos( double const Horizontal, double const Vertical ) override { ; }
void void on_mouse_button( int const Button, int const Action, int const Mods ) override { ; }
on_cursor_pos( double const Horizontal, double const Vertical ) override { ; } void on_scroll( double const Xoffset, double const Yoffset ) override { ; }
void void on_window_resize( int w, int h ) override;
on_mouse_button( int const Button, int const Action, int const Mods ) override { ; } void on_event_poll() override { ; }
void bool is_command_processor() const override { return false; }
on_scroll( double const Xoffset, double const Yoffset ) override { ; }
void
on_event_poll() override { ; }
bool
is_command_processor() const override { return false; }
}; };

View File

@@ -1,10 +1,9 @@
#include "stdafx.h" #include "stdafx.h"
#include "launcher/launcheruilayer.h" #include "launcher/launcheruilayer.h"
#include "application.h" #include "application.h"
#include "translation.h"
#include "Logs.h" launcher_ui::launcher_ui() : m_scenery_scanner(m_vehicles_bank), m_scenerylist_panel(m_scenery_scanner)
launcher_ui::launcher_ui()
: m_scenery_scanner(m_vehicles_bank), m_scenerylist_panel(m_scenery_scanner)
{ {
m_vehicles_bank.scan_textures(); m_vehicles_bank.scan_textures();
m_scenery_scanner.scan(); m_scenery_scanner.scan();
@@ -13,33 +12,66 @@ launcher_ui::launcher_ui()
add_external_panel(&m_keymapper_panel); add_external_panel(&m_keymapper_panel);
add_external_panel(&m_vehiclepicker_panel); add_external_panel(&m_vehiclepicker_panel);
open_panel(&m_vehiclepicker_panel);
m_suppress_menu = true;
load_random_background(); load_random_background();
} }
bool launcher_ui::on_key(const int Key, const int Action) bool launcher_ui::on_key(const int Key, const int Action)
{ {
if (m_scenerylist_panel.on_key(Key, Action))
return true;
if (m_keymapper_panel.key(Key)) if (m_keymapper_panel.key(Key))
return true; return true;
return ui_layer::on_key(Key, Action); return ui_layer::on_key(Key, Action);
} }
void launcher_ui::on_window_resize(int w, int h)
{
open_panel(m_current_panel);
}
void launcher_ui::render_() void launcher_ui::render_()
{ {
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse; ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove;
ImVec2 display_size = ImGui::GetIO().DisplaySize; const float topbar_height = 50 * Global.ui_scale;
ImGui::SetNextWindowPos(ImVec2(display_size.x * 0.66f, display_size.y / 2.0f)); const ImVec2 topbar_button_size = ImVec2(150 * Global.ui_scale, topbar_height - 16);
ImGui::SetNextWindowSize(ImVec2(200 * Global.ui_scale, -1)); ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(ImVec2(Global.window_size.x, topbar_height));
if (ImGui::Begin(STR_C("Main menu"), nullptr, flags)) { if (ImGui::Begin(STR_C("Main menu"), nullptr, flags)) {
if (ImGui::Button(STR_C("Scenario list"), ImVec2(-1, 0))) if (ImGui::Button(STR_C("Scenario list"), topbar_button_size))
m_scenerylist_panel.is_open = !m_scenerylist_panel.is_open; open_panel(&m_scenerylist_panel);
if (ImGui::Button(STR_C("Vehicle list"), ImVec2(-1, 0))) ImGui::SameLine();
m_vehiclepicker_panel.is_open = !m_vehiclepicker_panel.is_open; if (ImGui::Button(STR_C("Vehicle list"), topbar_button_size))
if (ImGui::Button(STR_C("Keymapper"), ImVec2(-1, 0))) open_panel(&m_vehiclepicker_panel);
m_keymapper_panel.is_open = !m_keymapper_panel.is_open; ImGui::SameLine();
if (ImGui::Button(STR_C("Quit"), ImVec2(-1, 0))) if (ImGui::Button(STR_C("Keymapper"), topbar_button_size))
open_panel(&m_keymapper_panel);
ImGui::SameLine();
if (ImGui::Button(STR_C("Quit"), topbar_button_size))
Application.queue_quit(false); Application.queue_quit(false);
} }
ImGui::End(); ImGui::End();
} }
void launcher_ui::close_panels()
{
m_scenerylist_panel.is_open = false;
m_vehiclepicker_panel.is_open = false;
m_keymapper_panel.is_open = false;
}
void launcher_ui::open_panel(ui_panel* panel)
{
close_panels();
const float topbar_height = 50 * Global.ui_scale;
panel->pos = glm::vec2(0, topbar_height);
panel->size = glm::vec2(Global.window_size.x, Global.window_size.y - topbar_height);
panel->no_title_bar = true;
panel->is_open = true;
m_current_panel = panel;
}

View File

@@ -19,10 +19,13 @@ http://mozilla.org/MPL/2.0/.
class launcher_ui : public ui_layer { class launcher_ui : public ui_layer {
public: public:
launcher_ui(); launcher_ui();
bool on_key(const int Key, const int Action) override; bool on_key(int Key, int Action) override;
void on_window_resize(int w, int h) override;
private: private:
void render_() override; void render_() override;
void close_panels();
void open_panel(ui_panel *panel);
ui::vehicles_bank m_vehicles_bank; ui::vehicles_bank m_vehicles_bank;
scenery_scanner m_scenery_scanner; scenery_scanner m_scenery_scanner;
@@ -30,4 +33,6 @@ private:
ui::scenerylist_panel m_scenerylist_panel; ui::scenerylist_panel m_scenerylist_panel;
ui::keymapper_panel m_keymapper_panel; ui::keymapper_panel m_keymapper_panel;
ui::vehiclepicker_panel m_vehiclepicker_panel; ui::vehiclepicker_panel m_vehiclepicker_panel;
ui_panel *m_current_panel;
}; };

View File

@@ -3,9 +3,10 @@
#include "imgui/imgui.h" #include "imgui/imgui.h"
#include "utilities.h" #include "utilities.h"
#include "renderer.h" #include "renderer.h"
#include "McZapkie/MOVER.h"
#include "application.h" #include "application.h"
#include "Logs.h" #include "Logs.h"
#include "translation.h"
#include <filesystem> #include <filesystem>
ui::scenerylist_panel::scenerylist_panel(scenery_scanner &scanner) ui::scenerylist_panel::scenerylist_panel(scenery_scanner &scanner)
@@ -13,37 +14,56 @@ ui::scenerylist_panel::scenerylist_panel(scenery_scanner &scanner)
{ {
} }
void ui::scenerylist_panel::draw_scenery_list() bool ui::scenerylist_panel::on_key(int key, int action)
{ {
std::string prev_prefix; if (!is_open)
bool collapse_open = false; return false;
for (auto &desc : scanner.scenarios) { auto it = keyboard.keytonamemap.find(key);
std::string name = desc.path.stem().string(); if (it == keyboard.keytonamemap.end())
std::string prefix = name.substr(0, name.find_first_of("-_")); return false;
if (prefix.empty())
prefix = name;
bool just_opened = false; if (Global.ctrlState && it->second == "delete")
if (prefix != prev_prefix) { purge_selected_trainset();
collapse_open = ImGui::CollapsingHeader(prefix.c_str());
just_opened = ImGui::IsItemDeactivated(); return true;
prev_prefix = prefix;
} }
if (collapse_open) { void ui::scenerylist_panel::draw_scenery_list()
if (just_opened) {
selected_scenery = &desc; // Draw all the scenarios which are not assigned to any category.
for (auto &desc : scanner.scenarios) {
ImGui::Indent(10.0f); std::string name = desc.path.stem().string();
std::string prefix = desc.category;
if (prefix.empty())
{
if (ImGui::Selectable(name.c_str(), &desc == selected_scenery)) { if (ImGui::Selectable(name.c_str(), &desc == selected_scenery)) {
selected_scenery = &desc; selected_scenery = &desc;
selected_trainset = nullptr; selected_trainset = nullptr;
} }
}
}
// Render all aggregated scenarios inside categories.
bool collapse_open = false;
for (auto category : scanner.categories)
{
collapse_open = ImGui::CollapsingHeader(category.first.c_str());
if (collapse_open) {
for (auto desc : category.second)
{
std::string name = desc->path.stem().string();
ImGui::Indent(10.0f);
if (ImGui::Selectable(name.c_str(), desc == selected_scenery)) {
selected_scenery = desc;
selected_trainset = nullptr;
}
ImGui::Unindent(10.0f); ImGui::Unindent(10.0f);
} }
} }
} }
}
void ui::scenerylist_panel::draw_scenery_info() void ui::scenerylist_panel::draw_scenery_info()
{ {
@@ -352,6 +372,11 @@ void ui::scenerylist_panel::draw_droptarget(trainset_desc &trainset, int positio
} }
} }
void ui::scenerylist_panel::purge_selected_trainset()
{
selected_trainset->vehicles.clear();
}
ui::dynamic_edit_popup::dynamic_edit_popup(ui_panel &panel, dynamic_desc &dynamic) ui::dynamic_edit_popup::dynamic_edit_popup(ui_panel &panel, dynamic_desc &dynamic)
: popup(panel), dynamic(dynamic) : popup(panel), dynamic(dynamic)
{ {

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "driverkeyboardinput.h"
#include "uilayer.h" #include "uilayer.h"
#include "scenery_scanner.h" #include "scenery_scanner.h"
#include "widgets/popup.h" #include "widgets/popup.h"
@@ -35,8 +36,11 @@ class scenerylist_panel : public ui_panel
scenerylist_panel(scenery_scanner &scanner); scenerylist_panel(scenery_scanner &scanner);
void render_contents() override; void render_contents() override;
bool on_key(int key, int action);
private: private:
driverkeyboard_input keyboard;
struct vehicle_moved { struct vehicle_moved {
trainset_desc &source; trainset_desc &source;
dynamic_desc &dynamic; dynamic_desc &dynamic;
@@ -63,5 +67,6 @@ private:
void open_link(const std::string &link); void open_link(const std::string &link);
void draw_trainset(trainset_desc &trainset); void draw_trainset(trainset_desc &trainset);
void draw_droptarget(trainset_desc &trainset, int position); void draw_droptarget(trainset_desc &trainset, int position);
void purge_selected_trainset();
}; };
} // namespace ui } // namespace ui

View File

@@ -22,6 +22,8 @@ void scenery_scanner::scan()
std::sort(scenarios.begin(), scenarios.end(), std::sort(scenarios.begin(), scenarios.end(),
[](const scenery_desc &a, const scenery_desc &b) { return a.path < b.path; }); [](const scenery_desc &a, const scenery_desc &b) { return a.path < b.path; });
build_categories();
} }
void scenery_scanner::scan_scn(std::filesystem::path path) void scenery_scanner::scan_scn(std::filesystem::path path)
@@ -57,6 +59,8 @@ void scenery_scanner::scan_scn(std::filesystem::path path)
desc.name = win1250_to_utf8(line.substr(5)); desc.name = win1250_to_utf8(line.substr(5));
else if (line[3] == 'd') else if (line[3] == 'd')
desc.description += win1250_to_utf8(line.substr(5)) + '\n'; desc.description += win1250_to_utf8(line.substr(5)) + '\n';
else if (line[3] == 'l')
desc.category = win1250_to_utf8(line.substr(5));
else if (line[3] == 'f') { else if (line[3] == 'f') {
std::string lang; std::string lang;
std::string file; std::string file;
@@ -154,3 +158,14 @@ void scenery_scanner::parse_trainset(cParser &parser)
trainset.file_bounds.second = parser.Line(); trainset.file_bounds.second = parser.Line();
} }
void scenery_scanner::build_categories()
{
for (auto &desc : scenarios) {
std::string name = desc.path.stem().string();
std::string prefix = desc.category;
// If the scenario does have a category, add it to the list so we can render it later in a group.
if (!prefix.empty())
categories[prefix].push_back(&desc);
}
}

View File

@@ -39,6 +39,7 @@ struct scenery_desc {
std::filesystem::path path; std::filesystem::path path;
std::string name; std::string name;
std::string description; std::string description;
std::string category;
std::string image_path; std::string image_path;
texture_handle image = 0; texture_handle image = 0;
@@ -58,12 +59,14 @@ public:
scenery_scanner(ui::vehicles_bank &bank); scenery_scanner(ui::vehicles_bank &bank);
std::vector<scenery_desc> scenarios; std::vector<scenery_desc> scenarios;
std::map<std::string, std::vector<scenery_desc*>> categories;
void scan(); void scan();
private: private:
void scan_scn(std::filesystem::path path); void scan_scn(std::filesystem::path path);
void parse_trainset(cParser &parser); void parse_trainset(cParser &parser);
void build_categories();
ui::vehicles_bank &bank; ui::vehicles_bank &bank;
}; };

View File

@@ -1,6 +1,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "launcher/vehicle_picker.h" #include "launcher/vehicle_picker.h"
#include "renderer.h" #include "renderer.h"
#include "translation.h"
ui::vehiclepicker_panel::vehiclepicker_panel() ui::vehiclepicker_panel::vehiclepicker_panel()
: ui_panel(STR("Select vehicle"), false), placeholder_mini("textures/mini/other") : ui_panel(STR("Select vehicle"), false), placeholder_mini("textures/mini/other")
@@ -8,31 +9,8 @@ ui::vehiclepicker_panel::vehiclepicker_panel()
bank.scan_textures(); bank.scan_textures();
} }
void ui::vehiclepicker_panel::render() void ui::vehiclepicker_panel::render_contents()
{ {
if (!is_open)
return;
static std::map<vehicle_type, std::string> type_names =
{
{ vehicle_type::electric_loco, STRN("Electric locos") },
{ vehicle_type::diesel_loco, STRN("Diesel locos") },
{ vehicle_type::steam_loco, STRN("Steam locos") },
{ vehicle_type::railcar, STRN("Railcars") },
{ vehicle_type::emu, STRN("EMU") },
{ vehicle_type::utility, STRN("Utility") },
{ vehicle_type::draisine, STRN("Draisines") },
{ vehicle_type::tram, STRN("Trams") },
{ vehicle_type::carriage, STRN("Carriages") },
{ vehicle_type::truck, STRN("Trucks") },
{ vehicle_type::bus, STRN("Buses") },
{ vehicle_type::car, STRN("Cars") },
{ vehicle_type::man, STRN("People") },
{ vehicle_type::animal, STRN("Animals") },
{ vehicle_type::unknown, STRN("Unknown") }
};
if (ImGui::Begin(m_name.c_str(), &is_open)) {
ImGui::Columns(3); ImGui::Columns(3);
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.0f, 0.5f)); ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.0f, 0.5f));
@@ -196,8 +174,6 @@ void ui::vehiclepicker_panel::render()
ImGui::PopStyleVar(); ImGui::PopStyleVar();
} }
ImGui::End();
}
std::vector<ui::vehiclepicker_panel::search_info> ui::vehiclepicker_panel::parse_search_query(const std::string &str) std::vector<ui::vehiclepicker_panel::search_info> ui::vehiclepicker_panel::parse_search_query(const std::string &str)
{ {

View File

@@ -2,6 +2,7 @@
#include "uilayer.h" #include "uilayer.h"
#include "textures_scanner.h" #include "textures_scanner.h"
#include "translation.h"
namespace ui { namespace ui {
@@ -10,7 +11,7 @@ class vehiclepicker_panel : public ui_panel
public: public:
vehiclepicker_panel(); vehiclepicker_panel();
void render() override; void render_contents() override;
private: private:
bool selectable_image(const char *desc, bool selected, const deferred_image *image, const skin_set *pickable = nullptr); bool selectable_image(const char *desc, bool selected, const deferred_image *image, const skin_set *pickable = nullptr);
@@ -22,6 +23,24 @@ private:
bool display_by_groups = true; bool display_by_groups = true;
deferred_image placeholder_mini; deferred_image placeholder_mini;
std::array<char, 128> search_query = { 0 }; std::array<char, 128> search_query = { 0 };
std::map<vehicle_type, std::string> type_names =
{
{ vehicle_type::electric_loco, STRN("Electric locos") },
{ vehicle_type::diesel_loco, STRN("Diesel locos") },
{ vehicle_type::steam_loco, STRN("Steam locos") },
{ vehicle_type::railcar, STRN("Railcars") },
{ vehicle_type::emu, STRN("EMU") },
{ vehicle_type::utility, STRN("Utility") },
{ vehicle_type::draisine, STRN("Draisines") },
{ vehicle_type::tram, STRN("Trams") },
{ vehicle_type::carriage, STRN("Carriages") },
{ vehicle_type::truck, STRN("Trucks") },
{ vehicle_type::bus, STRN("Buses") },
{ vehicle_type::car, STRN("Cars") },
{ vehicle_type::man, STRN("People") },
{ vehicle_type::animal, STRN("Animals") },
{ vehicle_type::unknown, STRN("Unknown") }
};
vehicles_bank bank; vehicles_bank bank;

View File

@@ -14,7 +14,6 @@ http://mozilla.org/MPL/2.0/.
#include "simulation.h" #include "simulation.h"
#include "simulationtime.h" #include "simulationtime.h"
#include "simulationenvironment.h" #include "simulationenvironment.h"
#include "Timer.h"
#include "application.h" #include "application.h"
#include "scenarioloaderuilayer.h" #include "scenarioloaderuilayer.h"
#include "renderer.h" #include "renderer.h"
@@ -22,20 +21,17 @@ http://mozilla.org/MPL/2.0/.
#include "translation.h" #include "translation.h"
scenarioloader_mode::scenarioloader_mode() { scenarioloader_mode::scenarioloader_mode() {
m_userinterface = std::make_shared<scenarioloader_ui>(); m_userinterface = std::make_shared<scenarioloader_ui>();
} }
// initializes internal data structures of the mode. returns: true on success, false otherwise // initializes internal data structures of the mode. returns: true on success, false otherwise
bool bool scenarioloader_mode::init() {
scenarioloader_mode::init() {
// nothing to do here // nothing to do here
return true; return true;
} }
// mode-specific update of simulation data. returns: false on error, true otherwise // mode-specific update of simulation data. returns: false on error, true otherwise
bool bool scenarioloader_mode::update() {
scenarioloader_mode::update() {
if (!Global.ready_to_load) if (!Global.ready_to_load)
// waiting for network connection // waiting for network connection
return true; return true;
@@ -69,30 +65,23 @@ scenarioloader_mode::update() {
return true; return true;
} }
bool bool scenarioloader_mode::is_command_processor() const {
scenarioloader_mode::is_command_processor() const {
return false; return false;
} }
// maintenance method, called when the mode is activated // maintenance method, called when the mode is activated
void void scenarioloader_mode::enter() {
scenarioloader_mode::enter() {
// TBD: hide cursor in fullscreen mode? // TBD: hide cursor in fullscreen mode?
Application.set_cursor( GLFW_CURSOR_NORMAL ); Application.set_cursor( GLFW_CURSOR_NORMAL );
simulation::is_ready = false; simulation::is_ready = false;
m_userinterface->set_background( "logo" );
Application.set_title( Global.AppName + " (" + Global.SceneryFile + ")" ); Application.set_title( Global.AppName + " (" + Global.SceneryFile + ")" );
m_userinterface->set_progress();
m_userinterface->set_progress(STR("Loading scenery")); m_userinterface->set_progress(STR("Loading scenery"));
} }
// maintenance method, called when the mode is deactivated // maintenance method, called when the mode is deactivated
void void scenarioloader_mode::exit() {
scenarioloader_mode::exit() {
simulation::Time.init( Global.starting_timestamp ); simulation::Time.init( Global.starting_timestamp );
simulation::Environment.init(); simulation::Environment.init();
} }

View File

@@ -21,28 +21,19 @@ public:
scenarioloader_mode(); scenarioloader_mode();
// methods // methods
// initializes internal data structures of the mode. returns: true on success, false otherwise // initializes internal data structures of the mode. returns: true on success, false otherwise
bool bool init() override;
init() override;
// mode-specific update of simulation data. returns: false on error, true otherwise // mode-specific update of simulation data. returns: false on error, true otherwise
bool bool update() override;
update() override;
// maintenance method, called when the mode is activated // maintenance method, called when the mode is activated
void void enter() override;
enter() override;
// maintenance method, called when the mode is deactivated // maintenance method, called when the mode is deactivated
void void exit() override;
exit() override;
// input handlers // input handlers
void void on_key( int const Key, int const Scancode, int const Action, int const Mods ) override { ; }
on_key( int const Key, int const Scancode, int const Action, int const Mods ) override { ; } void on_cursor_pos( double const Horizontal, double const Vertical ) override { ; }
void void on_mouse_button( int const Button, int const Action, int const Mods ) override { ; }
on_cursor_pos( double const Horizontal, double const Vertical ) override { ; } void on_scroll( double const Xoffset, double const Yoffset ) override { ; }
void void on_window_resize( int w, int h ) override { ; }
on_mouse_button( int const Button, int const Action, int const Mods ) override { ; } void on_event_poll() override { ; }
void bool is_command_processor() const override;
on_scroll( double const Xoffset, double const Yoffset ) override { ; }
void
on_event_poll() override { ; }
bool
is_command_processor() const override;
}; };

109
scenarioloaderuilayer.cpp Normal file
View File

@@ -0,0 +1,109 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#include "scenarioloaderuilayer.h"
#include "Globals.h"
#include "translation.h"
scenarioloader_ui::scenarioloader_ui()
{
m_suppress_menu = true;
load_random_background();
generate_gradient_tex();
load_wheel_frames();
// Temorary trivia contents
m_trivia.push_back("W trakcie przeprowadzonej rewizji technicznej wagonów kolejowych");
m_trivia.push_back("sprawdza się również daty ostatnich napraw okresowych. Wagony, dla");
m_trivia.push_back("których upływa termin dokonania następnej naprawy okresowej pracownik");
m_trivia.push_back("zespołu rewizji technicznej prowadzący oględziny winien jest przekierować");
m_trivia.push_back("do odpowiednich Zakładów Naprawczych Taboru Kolejowego lub wagonowni.");
}
void scenarioloader_ui::render_()
{
// For some reason, ImGui windows have some padding. Offset it.
// TODO: Find out a way to exactly adjust the position.
constexpr int padding = 12;
ImGui::SetNextWindowPos(ImVec2(-padding, -padding));
ImGui::SetNextWindowSize(ImVec2(Global.window_size.x + padding * 2, Global.window_size.y + padding * 2));
ImGui::Begin("Neo Loading Screen", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoBackground);
ImDrawList* draw_list = ImGui::GetWindowDrawList();
ImGui::PushFont(font_loading);
ImGui::SetWindowFontScale(1);
const float font_scale_mult = 48 / ImGui::GetFontSize();
// Gradient at the lower half of the screen
const auto tex = reinterpret_cast<ImTextureID>(m_gradient_overlay_tex);
draw_list->AddImage(tex, ImVec2(0, Global.window_size.y / 2), ImVec2(Global.window_size.x, Global.window_size.y), ImVec2(0, 0), ImVec2(1, 1));
// Loading label
ImGui::SetWindowFontScale(font_scale_mult * 0.8);
draw_list->AddText(ImVec2(200, 885), IM_COL32_WHITE, m_progresstext.c_str());
// Loading wheel icon
const deferred_image* img = &m_loading_wheel_frames[38];
const auto loading_tex = img->get();
const auto loading_size = img->size();
draw_list->AddImage(reinterpret_cast<ImTextureID>(loading_tex), ImVec2(35, 850), ImVec2(35 + loading_size.x, 850 + loading_size.y), ImVec2(0, 0), ImVec2(1, 1));
// Trivia header
ImGui::SetWindowFontScale(font_scale_mult * 1);
draw_list->AddText(ImVec2(1280 - ImGui::CalcTextSize(STR_C("Did you know")).x / 2, 770), IM_COL32_WHITE, STR_C("Did you know"));
// Trivia content
ImGui::SetWindowFontScale(font_scale_mult * 0.6);
for (int i = 0; i < m_trivia.size(); i++)
{
std::string line = m_trivia[i];
draw_list->AddText(ImVec2(1280 - ImGui::CalcTextSize(line.c_str()).x / 2, 825 + i * 25), IM_COL32_WHITE, line.c_str());
}
// Progress bar at the bottom of the screen
const auto p1 = ImVec2(0, Global.window_size.y - 2);
const auto p2 = ImVec2(Global.window_size.x * m_progress, Global.window_size.y);
draw_list->AddRectFilled(p1, p2, ImColor(40, 210, 60, 255));
ImGui::PopFont();
ImGui::End();
}
void scenarioloader_ui::generate_gradient_tex()
{
constexpr int image_width = 1;
constexpr int image_height = 256;
const auto image_data = new char[image_width * image_height * 4];
for (int x = 0; x < image_width; x++)
for (int y = 0; y < image_height; y++)
{
image_data[(y * image_width + x) * 4] = 0;
image_data[(y * image_width + x) * 4 + 1] = 0;
image_data[(y * image_width + x) * 4 + 2] = 0;
image_data[(y * image_width + x) * 4 + 3] = clamp(static_cast<int>(pow(y / 255.f, 0.7) * 255), 0, 255);
}
// Create a OpenGL texture identifier
GLuint image_texture;
glGenTextures(1, &image_texture);
glBindTexture(GL_TEXTURE_2D, image_texture);
// Setup filtering parameters for display
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Upload pixels into texture
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width, image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
delete[] image_data;
m_gradient_overlay_width = image_width;
m_gradient_overlay_height = image_height;
m_gradient_overlay_tex = image_texture;
}
void scenarioloader_ui::load_wheel_frames()
{
for (int i = 0; i < 60; i++)
m_loading_wheel_frames[i] = deferred_image("ui/loading_wheel/" + std::to_string(i + 1));
}

View File

@@ -10,11 +10,18 @@ http://mozilla.org/MPL/2.0/.
#pragma once #pragma once
#include "uilayer.h" #include "uilayer.h"
#include "launcher/deferred_image.h"
class scenarioloader_ui : public ui_layer { class scenarioloader_ui : public ui_layer {
int m_gradient_overlay_width;
int m_gradient_overlay_height;
GLuint m_gradient_overlay_tex;
deferred_image m_loading_wheel_frames[60];
std::vector<std::string> m_trivia;
public: public:
scenarioloader_ui() : ui_layer() { scenarioloader_ui();
load_random_background(); void render_() override;
} private:
// TODO: implement mode-specific elements void generate_gradient_tex();
void load_wheel_frames();
}; };

View File

@@ -330,6 +330,7 @@ public:
export_as_text( std::string &Output ) const; export_as_text( std::string &Output ) const;
std::string const & std::string const &
name() const; name() const;
virtual std::string tooltip() const;
void void
location( glm::dvec3 const Location ); location( glm::dvec3 const Location );
glm::dvec3 const & glm::dvec3 const &
@@ -379,6 +380,13 @@ basic_node::name() const {
return m_name; return m_name;
} }
// Returns the tooltip of this Node when hovered with the mouse cursor.
inline
std::string basic_node::tooltip() const
{
return m_name;
}
inline inline
void void
basic_node::location( glm::dvec3 const Location ) { basic_node::location( glm::dvec3 const Location ) {

View File

@@ -10,10 +10,11 @@ http://mozilla.org/MPL/2.0/.
#include "stdafx.h" #include "stdafx.h"
#include "uilayer.h" #include "uilayer.h"
#include <utility>
#include "Globals.h" #include "Globals.h"
#include "renderer.h" #include "renderer.h"
#include "Logs.h" #include "Logs.h"
#include "Timer.h"
#include "simulation.h" #include "simulation.h"
#include "translation.h" #include "translation.h"
#include "application.h" #include "application.h"
@@ -26,8 +27,9 @@ GLint ui_layer::m_textureunit { GL_TEXTURE0 };
bool ui_layer::m_cursorvisible; bool ui_layer::m_cursorvisible;
ImFont *ui_layer::font_default{nullptr}; ImFont *ui_layer::font_default{nullptr};
ImFont *ui_layer::font_mono{nullptr}; ImFont *ui_layer::font_mono{nullptr};
ImFont *ui_layer::font_loading{nullptr};
ui_panel::ui_panel(std::string const &Identifier, bool const Isopen) : m_name(Identifier), is_open(Isopen) {} ui_panel::ui_panel(std::string Identifier, bool const Isopen) : is_open(Isopen), m_name(std::move(Identifier)) {}
void ui_panel::render() void ui_panel::render()
{ {
@@ -36,11 +38,16 @@ void ui_panel::render()
int flags = window_flags; int flags = window_flags;
if (flags == -1) if (flags == -1)
flags = ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoCollapse | flags = ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoCollapse;
((size.x > 0) ? ImGuiWindowFlags_NoResize : 0);
if (size.x > 0) if (size.x > 0)
ImGui::SetNextWindowSize(ImVec2S(size.x, size.y)); flags |= ImGuiWindowFlags_NoResize;
if (no_title_bar)
flags |= ImGuiWindowFlags_NoTitleBar;
if (pos.x != -1 && pos.y != -1)
ImGui::SetNextWindowPos(ImVec2(pos.x, pos.y), ImGuiCond_Always);
if (size.x > 0)
ImGui::SetNextWindowSize(ImVec2S(size.x, size.y), ImGuiCond_Always);
else if (size_min.x == -1) else if (size_min.x == -1)
ImGui::SetNextWindowSize(ImVec2(0, 0), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(0, 0), ImGuiCond_FirstUseEver);
@@ -51,7 +58,7 @@ void ui_panel::render()
if (ImGui::Begin(panelname.c_str(), &is_open, flags)) { if (ImGui::Begin(panelname.c_str(), &is_open, flags)) {
render_contents(); render_contents();
popups.remove_if([](std::unique_ptr<ui::popup> &popup) popups.remove_if([](const std::unique_ptr<ui::popup> &popup)
{ {
return popup->render(); return popup->render();
}); });
@@ -91,6 +98,13 @@ void ui_log_panel::render_contents()
ImGui::PopFont(); ImGui::PopFont();
} }
ui_layer::ui_layer()
{
if (Global.loading_log)
add_external_panel(&m_logpanel);
m_logpanel.size = { 700, 400 };
}
ui_layer::~ui_layer() {} ui_layer::~ui_layer() {}
bool ui_layer::key_callback(int key, int scancode, int action, int mods) bool ui_layer::key_callback(int key, int scancode, int action, int mods)
@@ -117,14 +131,7 @@ bool ui_layer::mouse_button_callback(int button, int action, int mods)
return m_imguiio->WantCaptureMouse; return m_imguiio->WantCaptureMouse;
} }
ui_layer::ui_layer() void ui_layer::load_random_background()
{
if (Global.loading_log)
add_external_panel(&m_logpanel);
m_logpanel.size = { 700, 400 };
}
void::ui_layer::load_random_background()
{ {
std::vector<std::string> images; std::vector<std::string> images;
for (auto &f : std::filesystem::directory_iterator("textures/logo")) for (auto &f : std::filesystem::directory_iterator("textures/logo"))
@@ -225,6 +232,8 @@ bool ui_layer::init(GLFWwindow *Window)
font_default = m_imguiio->Fonts->AddFontFromFileTTF("fonts/dejavusans.ttf", Global.ui_fontsize, nullptr, &ranges[0]); font_default = m_imguiio->Fonts->AddFontFromFileTTF("fonts/dejavusans.ttf", Global.ui_fontsize, nullptr, &ranges[0]);
if (FileExists("fonts/dejavusansmono.ttf")) if (FileExists("fonts/dejavusansmono.ttf"))
font_mono = m_imguiio->Fonts->AddFontFromFileTTF("fonts/dejavusansmono.ttf", Global.ui_fontsize, nullptr, &ranges[0]); font_mono = m_imguiio->Fonts->AddFontFromFileTTF("fonts/dejavusansmono.ttf", Global.ui_fontsize, nullptr, &ranges[0]);
if (FileExists("fonts/bahnschrift.ttf"))
font_loading = m_imguiio->Fonts->AddFontFromFileTTF("fonts/bahnschrift.ttf", 48, nullptr, &ranges[0]);
if (!font_default && !font_mono) if (!font_default && !font_mono)
font_default = font_mono = m_imguiio->Fonts->AddFontDefault(); font_default = font_mono = m_imguiio->Fonts->AddFontDefault();
@@ -232,6 +241,8 @@ bool ui_layer::init(GLFWwindow *Window)
font_default = font_mono; font_default = font_mono;
else if (!font_mono) else if (!font_mono)
font_mono = font_default; font_mono = font_default;
if (!font_loading)
font_loading = font_default;
imgui_style(); imgui_style();
@@ -298,6 +309,13 @@ bool ui_layer::on_mouse_button(int const Button, int const Action)
return false; return false;
} }
void ui_layer::on_window_resize(int w, int h)
{
for (auto *panel : m_panels)
panel->on_window_resize(w, h);
}
void ui_layer::update() void ui_layer::update()
{ {
for (auto *panel : m_panels) for (auto *panel : m_panels)
@@ -313,7 +331,6 @@ void ui_layer::update()
void ui_layer::render() void ui_layer::render()
{ {
render_background(); render_background();
render_progress();
render_panels(); render_panels();
render_tooltip(); render_tooltip();
render_menu(); render_menu();
@@ -366,26 +383,20 @@ void ui_layer::set_cursor(int const Mode)
m_cursorvisible = (Mode != GLFW_CURSOR_DISABLED); m_cursorvisible = (Mode != GLFW_CURSOR_DISABLED);
} }
void ui_layer::set_progress(float const Progress, float const Subtaskprogress) void ui_layer::set_progress(std::string const &Text)
{ {
m_progress = Progress * 0.01f; m_progresstext = Text;
m_subtaskprogress = Subtaskprogress * 0.01f; }
void ui_layer::set_progress(float const progress, float const subtaskprogress)
{
m_progress = progress * 0.01f;
m_subtaskprogress = subtaskprogress * 0.01f;
} }
void ui_layer::set_background(std::string const &Filename) void ui_layer::set_background(std::string const &Filename)
{ {
if (false == Filename.empty()) m_background = Filename.empty() ? null_handle : GfxRenderer->Fetch_Texture(Filename);
{
m_background = GfxRenderer->Fetch_Texture(Filename);
}
else
{
m_background = null_handle;
}
if (m_background != null_handle)
{
auto const &texture = GfxRenderer->Texture(m_background);
}
} }
void ui_layer::clear_panels() void ui_layer::clear_panels()
@@ -406,22 +417,6 @@ void ui_layer::add_owned_panel(ui_panel *Panel)
m_ownedpanels.emplace_back( Panel ); m_ownedpanels.emplace_back( Panel );
} }
void ui_layer::render_progress()
{
if ((m_progress == 0.0f) && (m_subtaskprogress == 0.0f))
return;
ImGui::SetNextWindowPos(ImVec2(50, 50));
ImGui::SetNextWindowSize(ImVec2(0, 0));
ImGui::Begin(STR_C("Loading"), nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
if (!m_progresstext.empty())
ImGui::ProgressBar(m_progress, ImVec2(300, 0), m_progresstext.c_str());
else
ImGui::ProgressBar(m_progress, ImVec2(300, 0));
ImGui::ProgressBar(m_subtaskprogress, ImVec2(300, 0));
ImGui::End();
}
void ui_layer::render_panels() void ui_layer::render_panels()
{ {
for (auto *panel : m_panels) for (auto *panel : m_panels)
@@ -486,7 +481,7 @@ void ui_layer::render_menu()
{ {
glm::dvec2 mousepos = Global.cursor_pos; glm::dvec2 mousepos = Global.cursor_pos;
if (!((Global.ControlPicking && mousepos.y < 50.0f) || m_imguiio->WantCaptureMouse) || m_progress != 0.0f) if (!((Global.ControlPicking && mousepos.y < 50.0f) || m_imguiio->WantCaptureMouse) || m_suppress_menu)
return; return;
if (ImGui::BeginMainMenuBar()) if (ImGui::BeginMainMenuBar())

123
uilayer.h
View File

@@ -11,7 +11,6 @@ http://mozilla.org/MPL/2.0/.
#include <string> #include <string>
#include "Texture.h" #include "Texture.h"
#include "translation.h"
#include "widgets/popup.h" #include "widgets/popup.h"
// GuiLayer -- basic user interface class. draws requested information on top of openGL screen // GuiLayer -- basic user interface class. draws requested information on top of openGL screen
@@ -20,32 +19,31 @@ class ui_panel {
public: public:
// constructor // constructor
ui_panel( std::string const &Identifier, bool const Isopen ); ui_panel( std::string Identifier, bool Isopen );
virtual ~ui_panel() = default; virtual ~ui_panel() = default;
// methods // methods
virtual void update() {}; virtual void update() {}
virtual void on_window_resize(int w, int h) {}
virtual void render(); virtual void render();
virtual void render_contents(); virtual void render_contents();
// temporary access // temporary access
// types // types
struct text_line { struct text_line {
std::string data; std::string data;
glm::vec4 color; glm::vec4 color;
text_line( std::string const &Data, glm::vec4 const &Color) : data(Data), color(Color) {}
text_line( std::string const &Data, glm::vec4 const &Color)
: data(Data), color(Color)
{}
}; };
// members // members
std::string title; std::string title;
bool is_open; bool is_open;
glm::ivec2 pos { -1, -1 };
glm::ivec2 size { -1, -1 }; glm::ivec2 size { -1, -1 };
glm::ivec2 size_min { -1, -1 }; glm::ivec2 size_min { -1, -1 };
glm::ivec2 size_max { -1, -1 }; glm::ivec2 size_max { -1, -1 };
std::deque<text_line> text_lines; std::deque<text_line> text_lines;
int window_flags = -1; int window_flags = -1;
bool no_title_bar = false;
const std::string& name() { return m_name; } const std::string& name() { return m_name; }
void register_popup(std::unique_ptr<ui::popup> &&popup); void register_popup(std::unique_ptr<ui::popup> &&popup);
@@ -59,19 +57,16 @@ protected:
class ui_expandable_panel : public ui_panel { class ui_expandable_panel : public ui_panel {
public: public:
using ui_panel::ui_panel; using ui_panel::ui_panel;
bool is_expanded { false }; bool is_expanded { false };
void render_contents() override; void render_contents() override;
}; };
class ui_log_panel : public ui_panel { class ui_log_panel : public ui_panel {
using ui_panel::ui_panel; using ui_panel::ui_panel;
void render_contents() override; void render_contents() override;
}; };
class ImFont; struct ImFont;
class ui_layer { class ui_layer {
public: public:
@@ -81,68 +76,40 @@ public:
virtual ~ui_layer(); virtual ~ui_layer();
// methods // methods
static static bool init( GLFWwindow *Window );
bool static void imgui_style();
init( GLFWwindow *Window );
static
void
imgui_style();
// assign texturing hardware unit // assign texturing hardware unit
static static void set_unit( GLint const Textureunit ) { m_textureunit = GL_TEXTURE0 + Textureunit; }
void static void shutdown();
set_unit( GLint const Textureunit ) { m_textureunit = GL_TEXTURE0 + Textureunit; }
static
void
shutdown();
// potentially processes provided input key. returns: true if the input was processed, false otherwise // potentially processes provided input key. returns: true if the input was processed, false otherwise
virtual virtual bool on_key( int Key, int Action );
bool
on_key( int const Key, int const Action );
// potentially processes provided mouse movement. returns: true if the input was processed, false otherwise // potentially processes provided mouse movement. returns: true if the input was processed, false otherwise
virtual virtual bool on_cursor_pos( double Horizontal, double Vertical );
bool
on_cursor_pos( double const Horizontal, double const Vertical );
// potentially processes provided mouse button. returns: true if the input was processed, false otherwise // potentially processes provided mouse button. returns: true if the input was processed, false otherwise
virtual virtual bool on_mouse_button( int Button, int Action );
bool // processes window resize.
on_mouse_button( int const Button, int const Action ); virtual void on_window_resize(int w, int h);
// updates state of UI elements // updates state of UI elements
virtual virtual void update();
void
update();
// draws requested UI elements // draws requested UI elements
void void render();
render(); static void render_internal();
static void
render_internal();
// begins new UI frame // begins new UI frame
// (this is separate from render() to allow for debug GUI outside of proper UI framework) // (this is separate from render() to allow for debug GUI outside of proper UI framework)
void void begin_ui_frame();
begin_ui_frame(); static void begin_ui_frame_internal();
static void
begin_ui_frame_internal();
// //
static static void set_cursor( int Mode );
void // loading
set_cursor( int const Mode ); void set_progress(std::string const &Text);
// stores operation progress void set_progress(float progress, float subtaskprogress);
void
set_progress( float const Progress = 0.0f, float const Subtaskprogress = 0.0f );
void
set_progress( std::string const &Text ) { m_progresstext = Text; }
// sets the ui background texture, if any // sets the ui background texture, if any
void void set_background( std::string const &Filename = "" );
set_background( std::string const &Filename = "" ); void set_tooltip( std::string const &Tooltip ) { m_tooltip = Tooltip; }
void void clear_panels();
set_tooltip( std::string const &Tooltip ) { m_tooltip = Tooltip; } void add_external_panel( ui_panel *Panel ) { m_panels.emplace_back( Panel ); }
void void add_owned_panel( ui_panel *Panel );
clear_panels();
void
add_external_panel( ui_panel *Panel ) { m_panels.emplace_back( Panel ); }
void
add_owned_panel( ui_panel *Panel );
// callback functions for imgui input // callback functions for imgui input
// returns true if input is consumed // returns true if input is consumed
@@ -153,6 +120,7 @@ public:
static ImFont *font_default; static ImFont *font_default;
static ImFont *font_mono; static ImFont *font_mono;
static ImFont *font_loading;
protected: protected:
// members // members
@@ -163,38 +131,27 @@ protected:
void load_random_background(); void load_random_background();
virtual void render_menu_contents(); virtual void render_menu_contents();
ui_log_panel m_logpanel { "Log", true }; ui_log_panel m_logpanel { "Log", true };
bool m_suppress_menu = false; // if `true`, the menu at the top of the window will not be present
// progress bar config
float m_progress { 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
float m_subtaskprogress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
std::string m_progresstext; // label placed over the progress bar
private: private:
// methods // methods
// render() subclass details // render() subclass details
virtual virtual void render_() {}
void
render_() {};
// draws background quad with specified earlier texture // draws background quad with specified earlier texture
void void render_background();
render_background(); void render_tooltip();
// draws a progress bar in defined earlier state
void
render_progress();
void
render_tooltip();
void render_panels(); void render_panels();
void render_menu(); void render_menu();
void render_quit_widget(); void render_quit_widget();
// draws a quad between coordinates x,y and z,w with uv-coordinates spanning 0-1 // draws a quad between coordinates x,y and z,w with uv-coordinates spanning 0-1
void void quad( glm::vec4 const &Coordinates, glm::vec4 const &Color );
quad( glm::vec4 const &Coordinates, glm::vec4 const &Color );
// members // members
static GLint m_textureunit; static GLint m_textureunit;
// progress bar config. TODO: put these together into an object
float m_progress { 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
float m_subtaskprogress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
std::string m_progresstext; // label placed over the progress bar
texture_handle m_background { null_handle }; // path to texture used as the background. size depends on mAspect. texture_handle m_background { null_handle }; // path to texture used as the background. size depends on mAspect.
std::vector<ui_panel *> m_panels; std::vector<ui_panel *> m_panels;
std::vector<std::unique_ptr<ui_panel>> m_ownedpanels; std::vector<std::unique_ptr<ui_panel>> m_ownedpanels;

View File

@@ -6,7 +6,7 @@
#include "widgets/cameraview_extcam.h" #include "widgets/cameraview_extcam.h"
#include "stb/stb_image.h" #include "stb/stb_image.h"
#include "Globals.h" #include "Globals.h"
#include "Logs.h" #include "translation.h"
#include "extras/piped_proc.h" #include "extras/piped_proc.h"
ui::cameraview_panel::cameraview_panel() ui::cameraview_panel::cameraview_panel()

View File

@@ -1,12 +1,9 @@
#include "stdafx.h" #include "stdafx.h"
#include "widgets/perfgraphs.h" #include "widgets/perfgraphs.h"
#include "Timer.h" #include "Timer.h"
#include "translation.h"
perfgraph_panel::perfgraph_panel() perfgraph_panel::perfgraph_panel() : ui_panel(STR("Performance"), false) {}
: ui_panel(STR("Performance"), false)
{
}
void perfgraph_panel::render_contents() { void perfgraph_panel::render_contents() {
if (ImGui::BeginCombo(STR_C("Timer"), timer_label[current_timer].c_str())) // The second parameter is the label previewed before opening the combo. if (ImGui::BeginCombo(STR_C("Timer"), timer_label[current_timer].c_str())) // The second parameter is the label previewed before opening the combo.