#pragma once #include "FluidSim/ScenarioSnapshot.hpp" #include "FluidSim/DynoCurve.hpp" #include "FluidSim/Desktop/PedalControl.hpp" #include "FluidSim/Desktop/EngineRenderer3D.hpp" #include #include #include namespace fluidsim::port::desktop { struct PlaybackInfo { float pedal_target{},load{}; double speed{1}; std::size_t buffered{},capacity{}; std::uint64_t underruns{}; bool auto_gain{},time_warp{}; }; struct WorkspaceLayout { sf::FloatRect sidebar,viewport,chart,inspector,pedal; static WorkspaceLayout calculate(sf::Vector2u size); }; class DesktopUi { public: float pedal() const {return pedal_.value();} void nudge_pedal(float amount) {pedal_.set(pedal_.value()+amount);} void update_pedal(float dt,bool raise,bool lower) {if(!pedal_drag_)pedal_.advance(dt,raise,lower);} bool handle_event(const sf::Event&,sf::Vector2u); AudioListener listener(const ScenarioSnapshot&,sf::Vector2u); void draw(sf::RenderWindow&,const sf::Font*,const ScenarioSnapshot&,const PlaybackInfo&); void configure_resolution(float density) { resolution_=density; } std::optional take_resolution_request() {auto value=resolution_request_;resolution_request_.reset();return value;} void resolution_started() {resolution_busy_=true;resolution_status_="Building mesh...";} void resolution_finished(float density,const std::string& message) {resolution_=density;resolution_busy_=false;resolution_status_=message;} static std::array resolution_buttons(sf::Vector2u size); private: DynoCurve dyno_; float resolution_{20}; bool resolution_busy_{}; std::optional resolution_request_; std::string resolution_status_; EngineRenderer3D renderer_; OrbitCamera camera_; bool three_d_{true},camera_fitted_{},pan_drag_{},pedal_drag_{}; PedalControl pedal_; sf::Vector2f pan_{}; sf::Vector2i previous_mouse_{}; bool dragging_{}; float zoom_{1}; float camera_aspect_{}; WorkspaceLayout workspace_layout(sf::Vector2u size) const; void fit_camera(float aspect,const ScenarioSnapshot&); }; }