From 85423d9ac9c30649969e15967f19aea632b1060b Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Sun, 3 May 2026 08:57:41 -0400 Subject: [PATCH] You can now do all of the control things you'd do in the control window via the bezos_cli/ctl command line tool. --- src/bezos_ctl.cpp | 42 +++++++++++++------ src/control_ui.cpp | 101 +++++++++++++++++++++++++++++++-------------- src/control_ui.hpp | 9 +++- src/main.cpp | 17 ++------ 4 files changed, 110 insertions(+), 59 deletions(-) diff --git a/src/bezos_ctl.cpp b/src/bezos_ctl.cpp index 54c6be5..4cb3b4b 100644 --- a/src/bezos_ctl.cpp +++ b/src/bezos_ctl.cpp @@ -11,31 +11,48 @@ const int DEFAULT_PORT=9898; struct Options { bool help{false}; - bool focus{false}; + CtrlCommand cmd{CtrlCommand::NONE}; bool error{false}; unsigned short port=DEFAULT_PORT; }; -void request_focus(Options& options) { - fmt::println("Moving control window front: port={}", options.port); +void send_request(Options& options) { sf::UdpSocket sock; - uint32_t cmd = uint32_t(CtrlCommand::FOCUS); + uint32_t cmd = uint32_t(options.cmd); auto localhost = sf::IpAddress::getLocalAddress(); + dbc::check(localhost != std::nullopt, "Failed to get local addres?!"); + auto result = sock.send(&cmd, sizeof cmd, *localhost, options.port); } void print_usage() { - fmt::println("USAGE: bezos [-p {}] [-hf] -d deck.md", DEFAULT_PORT); + fmt::println("USAGE: bezos [-p {}] [-h] [-fLRNPq]", DEFAULT_PORT); } Options parse_options(int argc, char* argv[]) { int opt = 0; Options result; - while((opt = getopt(argc, argv, "fhp:")) != -1) { + while((opt = getopt(argc, argv, "fLRNPqhp:")) != -1) { + using enum CtrlCommand; switch(opt) { + case 'L': + result.cmd = MOVE_LEFT; + break; + case 'R': + result.cmd = MOVE_RIGHT; + break; + case 'N': + result.cmd = NEXT_SLIDE; + break; + case 'P': + result.cmd = PREV_SLIDE; + break; + case 'q': + result.cmd = QUIT; + break; case 'f': - result.focus=true; + result.cmd = FOCUS; break; case 'h': print_usage(); @@ -50,23 +67,22 @@ Options parse_options(int argc, char* argv[]) { } } - if(!result.focus) { + if(result.cmd == CtrlCommand::NONE) { print_usage(); } return result; } - int main(int argc, char *argv[]) { auto options = parse_options(argc, argv); - if(options.focus) { - request_focus(options); - return 0; - } else if(options.help) { + if(options.help) { return 0; } else if(options.error) { return 1; + } else { + send_request(options); + return 0; } } diff --git a/src/control_ui.cpp b/src/control_ui.cpp index 3ddc5f0..52049bd 100644 --- a/src/control_ui.cpp +++ b/src/control_ui.cpp @@ -11,11 +11,13 @@ #include #include "constants.hpp" #include "control_ui.hpp" +#include -ControlUI::ControlUI(sf::RenderWindow& presenter, sf::RenderWindow& controller) : - $presenter(presenter), - $controller(controller), - $window_size($presenter.getSize()) +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( @@ -31,6 +33,8 @@ ControlUI::ControlUI(sf::RenderWindow& presenter, sf::RenderWindow& controller) } void ControlUI::init() { + $ctrl_sock.listen(); + auto status_id = $gui.entity("status"); $gui.set(status_id, {L""}); @@ -98,35 +102,72 @@ void ControlUI::full_screen(bool do_it) { $full_screen = do_it; } -void ControlUI::handle_events(std::shared_ptr slides, const sf::Event& event) { +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?!"); - if(event.is()) { - $controller.close(); - return; - } + process_commands(slides); + + while (const auto event = $controller.pollEvent()) { + if(event->is()) { + $controller.close(); + return; + } - if(const auto* key = event.getIf()) { - auto pos = $presenter.getPosition(); - - using KEY = sf::Keyboard::Scan; - switch(key->scancode) { - case KEY::A: { - pos.x -= $window_size.x; - $presenter.setPosition(pos); - } break; - case KEY::D: { - pos.x += int($window_size.x); - $presenter.setPosition(pos); - } break; - case KEY::Q: - $controller.close(); - break; - case KEY::F: - full_screen(!$full_screen); - break; - default: - slides->handle_events($controller, event); + 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); + } } } } diff --git a/src/control_ui.hpp b/src/control_ui.hpp index 31d358d..56d0356 100644 --- a/src/control_ui.hpp +++ b/src/control_ui.hpp @@ -3,6 +3,7 @@ #include "guecs/sfml/components.hpp" #include "guecs/ui.hpp" #include "slides_ui.hpp" +#include "control.hpp" struct ControlUI { bool $full_screen = true; @@ -11,11 +12,15 @@ struct ControlUI { sf::RenderWindow& $presenter; sf::RenderWindow& $controller; sf::Vector2u $window_size; + CtrlSocket $ctrl_sock; + + ControlUI(sf::RenderWindow& presenter, sf::RenderWindow& controller, unsigned short port); - ControlUI(sf::RenderWindow& presenter, sf::RenderWindow& controller); void init(); void render(sf::RenderWindow& window, SlideDeck& deck); - void handle_events(std::shared_ptr slides, const sf::Event& event); + void update(std::shared_ptr slides); void render_slide(const std::string& name, Slide& slide); void full_screen(bool do_it); + void process_commands(std::shared_ptr slides); + void move(int dir); }; diff --git a/src/main.cpp b/src/main.cpp index 97b3300..49ba269 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,7 +11,6 @@ #include #include #include -#include "control.hpp" using namespace std::chrono_literals; @@ -70,7 +69,7 @@ struct ChangeDetector { }; void print_usage() { - fmt::println("USAGE: bezos [-p PORT] [-hf] -d deck.md"); + fmt::println("USAGE: bezos [-p PORT] [-h] -d deck.md"); } Options parse_options(int argc, char* argv[]) { @@ -137,30 +136,20 @@ int main(int argc, char *argv[]) { return 1; } - ControlUI control_ui(presenter, controller); + ControlUI control_ui{presenter, controller, options.port}; control_ui.init(); control_ui.full_screen(false); - CtrlSocket ctrl_sock{options.port}; - ctrl_sock.listen(); - ChangeDetector slides_reloader{options.deck_file}; ChangeDetector layout_reloader{slides->$deck->config["layouts"]}; while(controller.isOpen()) { - auto command = ctrl_sock.receive(); - - if(command == CtrlCommand::FOCUS) { - sf::Mouse::setPosition({WINDOW_WIDTH - 100, WINDOW_HEIGHT - 100}, presenter); - } while(const auto event = presenter.pollEvent()) { if(event) slides->handle_events(presenter, *event); } - while (const auto event = controller.pollEvent()) { - if(event) control_ui.handle_events(slides, *event); - } + control_ui.update(slides); slides->render(presenter); control_ui.render(controller, *slides->$deck);