#include "FluidSim/Desktop/ScenarioMenu.hpp" #include "FluidSim/Desktop/WindowPresentation.hpp" #include "FluidSim/Machine.hpp" #include #include #include using namespace fluidsim::port; using namespace fluidsim::port::desktop; void check(bool value,const char* message){if(!value)throw std::runtime_error(message);} void key(ScenarioMenu& menu,sf::Keyboard::Key code,sf::Vector2u size={1280,720}){menu.handle_event(sf::Event::KeyPressed{.code=code},size);} void click(ScenarioMenu& menu,sf::Vector2i at,sf::Vector2u size={1280,720}){menu.handle_event(sf::Event::MouseButtonPressed{sf::Mouse::Button::Left,at},size);menu.handle_event(sf::Event::MouseButtonReleased{sf::Mouse::Button::Left,at},size);} int main(int argc,char** argv)try{ if(argc==2&&std::string(argv[1])=="--window-check"){ sf::RenderWindow window(sf::VideoMode({640,480}),"FluidSim maximize check");maximize_window(window); check(window_is_maximized(window),"Window did not enter the native maximized state");window.close();std::cout<<"Native window maximization passed\n";return 0; } const auto examples=scenario_examples();check(!examples.empty(),"Scenario catalog is empty"); ScenarioMenu workshop(examples,{"example.machine.toml"});check(workshop.screen()==MenuScreen::Home,"Menu did not start on Home"); key(workshop,sf::Keyboard::Key::Enter);check(workshop.screen()==MenuScreen::Workshop&&!workshop.take_choice(),"Workshop navigation launched a machine immediately"); key(workshop,sf::Keyboard::Key::Enter);auto choice=workshop.take_choice();check(choice&&!choice->example&&choice->machine.empty()&&!choice->play,"New machine choice is invalid"); key(workshop,sf::Keyboard::Key::Down);key(workshop,sf::Keyboard::Key::Space);choice=workshop.take_choice();check(choice&&choice->machine=="example.machine.toml"&&choice->play,"Saved machine Play did not preserve its path"); key(workshop,sf::Keyboard::Key::Enter);choice=workshop.take_choice();check(choice&&!choice->play&&!choice->example,"Saved machine Edit was treated as Play"); key(workshop,sf::Keyboard::Key::Escape);check(workshop.screen()==MenuScreen::Home&&!workshop.finished(),"Back closed the application instead of returning Home"); key(workshop,sf::Keyboard::Key::Down);key(workshop,sf::Keyboard::Key::Enter);check(workshop.screen()==MenuScreen::Scenarios,"Engine Scenarios did not open its own browser"); click(workshop,{350,180});check(!workshop.take_choice(),"Selecting an engine row started it immediately"); key(workshop,sf::Keyboard::Key::Enter);choice=workshop.take_choice();check(choice&&choice->example==0,"Engine browser lost catalog index mapping"); // Required keyboard focus keeps search text separate from navigation shortcuts. click(workshop,{350,120});for(char c:std::string("no-such-engine-xyz"))workshop.handle_event(sf::Event::TextEntered{std::uint32_t(c)},{1280,720}); key(workshop,sf::Keyboard::Key::Enter);key(workshop,sf::Keyboard::Key::Enter);check(!workshop.take_choice(),"Empty search launched an engine"); key(workshop,sf::Keyboard::Key::Escape);key(workshop,sf::Keyboard::Key::Enter);check(workshop.screen()==MenuScreen::Scenarios,"Returning to browser did not clear search"); click(workshop,{100,206});key(workshop,sf::Keyboard::Key::End);key(workshop,sf::Keyboard::Key::Enter);choice=workshop.take_choice();check(choice&&choice->example&&examples[*choice->example].category==examples.front().category,"Category selection started an engine from another category"); key(workshop,sf::Keyboard::Key::B);choice=workshop.take_choice();check(choice&&!choice->example&&choice->machine.empty(),"New machine keyboard shortcut failed"); ScenarioMenu empty({});key(empty,sf::Keyboard::Key::Enter);key(empty,sf::Keyboard::Key::Enter);check(bool(empty.take_choice()),"Empty engine catalog disabled the workshop"); ScenarioMenu quit(examples);key(quit,sf::Keyboard::Key::End);key(quit,sf::Keyboard::Key::Enter);check(quit.finished(),"Quit did not close the menu"); if(argc==3&&std::string(argv[1])=="--preview"){ const std::filesystem::path directory=argv[2];std::filesystem::create_directories(directory); sf::ContextSettings context;context.depthBits=24;context.majorVersion=2;context.minorVersion=1; sf::RenderWindow window(sf::VideoMode({1920,1080}),"Main menu review",sf::Style::Default,sf::State::Windowed,context);window.setVisible(false);sf::Font font("C:/Windows/Fonts/consola.ttf"); for(const sf::Vector2u size:{sf::Vector2u{1920,1080},sf::Vector2u{1280,720}}){ window.setSize(size);ScenarioMenu menu(examples,machine_files()); const auto capture=[&](const std::string& name){menu.draw(window,&font);sf::Texture image(size);image.update(window);check(image.copyToImage().saveToFile(directory/(std::to_string(size.x)+"-"+name+".png")),"Menu screenshot save failed");}; capture("home");key(menu,sf::Keyboard::Key::Down,size);key(menu,sf::Keyboard::Key::Enter,size);capture("engines"); click(menu,{350,120},size);const auto it=std::find_if(examples.begin(),examples.end(),[](const auto& example){return example.id=="flat6";}); if(it!=examples.end())for(char c:it->title)menu.handle_event(sf::Event::TextEntered{std::uint32_t(c)},size);key(menu,sf::Keyboard::Key::Enter,size);capture("engine-search"); key(menu,sf::Keyboard::Key::Escape,size);key(menu,sf::Keyboard::Key::Up,size);key(menu,sf::Keyboard::Key::Enter,size);capture("workshop"); key(menu,sf::Keyboard::Key::Down,size);capture("saved-machine"); } } std::cout<<"Main menu, workshop and scenario navigation passed\n";return 0; }catch(const std::exception& error){std::cerr<