#include "guecs/sfml/components.hpp" #include "guecs/ui.hpp" #include #include #include #include #include "dbc.hpp" #include #include #include #include #include "constants.hpp" #include "control_ui.hpp" #include ControlUI::ControlUI(sf::RenderWindow& presenter, sf::RenderWindow& controller, unsigned short port) : $presenter{presenter}, $controller{controller}, $window_size{$presenter.getSize()}, $ctrl_sock{port} { $gui.position(0, 0, CONTROL_WIDTH, CONTROL_HEIGHT); $gui.layout( "[status|*%(200,400)current|_]" "[title0|_|_]" "[title1|_|_]" "[title2|_|_]" "[title3|*%(200,400)preview|_]" "[title4|_|_]" "[title5|_|_]" "[help|_|_]" ); } void ControlUI::init() { $ctrl_sock.listen(); auto status_id = $gui.entity("status"); $gui.set(status_id, {L""}); auto docs_id = $gui.entity("help"); $gui.set(docs_id, { .content=L"F: fullscreen\nA: win left\nD: win right\nQ: quit", .size=20}); auto current = $gui.entity("current"); $gui.set(current, {}); $gui.set(current, {.content=L"CURRENT", .size=40}); auto preview = $gui.entity("preview"); $gui.set(preview, {.color=guecs::THEME.DARK_DARK}); $gui.set(preview, { .content=L"PREVIEW", .size=40, .color={180, 180, 180, 255} }); for(int i = 0; i < 6; i++) { auto id = $gui.entity("title", i); $gui.set(id, {.color=guecs::THEME.TRANSPARENT}); } $gui.init(); // warning! must come after init so the thing is there $status = $gui.get_if(status_id); dbc::check($status != nullptr, "failed to setup the status text"); } void ControlUI::render_slide(const std::string& name, Slide& slide) { $gui.show_text(name, slide.preview); } void ControlUI::render(sf::RenderWindow& window, SlideDeck& deck) { dbc::check($status != nullptr, "called render before init?"); auto pos = $presenter.getPosition(); auto size = $presenter.getSize(); $status->update(fmt::format(L"Slide: {}\nOf: {}", deck.current + 1, deck.slides.size())); window.clear(); $gui.render(window); render_slide("current", deck.current_slide()); size_t preview = std::min(deck.slides.size() - 1, deck.current + 1); render_slide("preview", deck.slide_at(preview)); } void ControlUI::full_screen(bool do_it) { if(do_it) { $presenter.setSize($window_size); $controller.requestFocus(); } else { $presenter.setSize({$window_size.x/2, $window_size.y/2}); $controller.requestFocus(); } $full_screen = do_it; } void ControlUI::process_commands(std::shared_ptr slides) { using enum CtrlCommand; switch($ctrl_sock.receive()) { case FOCUS: sf::Mouse::setPosition({WINDOW_WIDTH - 100, WINDOW_HEIGHT - 100}, $presenter); break; case FULL_SCREEN: full_screen(!$full_screen); break; case MOVE_LEFT: move(-1); break; case MOVE_RIGHT: move(1); break; case NEXT_SLIDE: slides->next_slide(); break; case PREV_SLIDE: slides->prev_slide(); break; case QUIT: $controller.close(); break; default: break; } } void ControlUI::move(int dir) { auto pos = $presenter.getPosition(); pos.x += dir * $window_size.x; $presenter.setPosition(pos); } void ControlUI::update(std::shared_ptr slides) { dbc::check($status != nullptr, "handle_events called before init?!"); process_commands(slides); while (const auto event = $controller.pollEvent()) { if(event->is()) { $controller.close(); return; } if(const auto* key = event->getIf()) { using KEY = sf::Keyboard::Scan; switch(key->scancode) { case KEY::A: move(-1); break; case KEY::D: move(1); break; case KEY::Q: $controller.close(); break; case KEY::F: full_screen(!$full_screen); break; default: slides->handle_events($controller, *event); } } } }