#pragma once #include #include #include namespace fluidsim::port::desktop { // One geometry source for drawing, picking and viewport projection. struct WorkshopLayout { sf::FloatRect left, right, viewport, library, search; float inspector_x{}, inspector_width{}, height{}, width{}; static constexpr float field_top=302, field_height=52; int field_rows()const{return std::max(1,int((height-164-field_top)/field_height));} int library_rows()const{return std::max(1,int(library.size.y/36));} sf::FloatRect field_row(int row)const{return {{inspector_x+12,field_top+row*field_height},{inspector_width-24,48}};} sf::FloatRect field_value(int row)const{auto r=field_row(row);return {{r.position.x,r.position.y+21},{r.size.x-68,26}};} static WorkshopLayout calculate(sf::Vector2u size,float left_width=260,float right_width=340,bool left_closed=false,bool right_closed=false){ WorkshopLayout l;l.width=float(size.x);l.height=float(size.y); const float available=std::max(480.f,l.width-440); float lw=left_closed?28.f:std::clamp(left_width,220.f,420.f),rw=right_closed?28.f:std::clamp(right_width,280.f,520.f); if(lw+rw>available){const float excess=lw+rw-available;rw=std::max(right_closed?28.f:280.f,rw-excess);lw=std::max(left_closed?28.f:180.f,std::min(lw,available-rw));} l.left={{8,96},{lw,std::max(100.f,l.height-154)}}; l.right={{l.width-rw-8,96},{rw,std::max(100.f,l.height-154)}}; l.inspector_x=l.right.position.x;l.inspector_width=rw; l.viewport={{l.left.position.x+lw+8,96},{std::max(100.f,l.right.position.x-lw-24),std::max(100.f,l.height-154)}}; l.search={{20,152},{lw-24,30}}; l.library={{20,230},{lw-24,std::max(36.f,l.height-474)}}; return l; } }; }