Hot reloading now works and you can toggle fullscreen so you can work on your presentation by just editing the file.

master
Zed A. Shaw 1 week ago
parent beee4381ea
commit cd6de86cb1
  1. 7
      sample/about-bezos.md
  2. 20
      src/control_ui.cpp
  3. 2
      src/control_ui.hpp
  4. 90
      src/main.cpp
  5. 17
      src/slides_ui.cpp
  6. 2
      src/slides_ui.hpp

@ -1,7 +1,7 @@
{ {
"title": "How to use Bezos", "title": "How to use Bezos",
"description": "A short presentation on Bezos.", "description": "A short presentation on Bezos.",
"font_file": "assets/text.otf" "font_file": "assets/bold.otf"
} }
=== ===
# Bezos Slide Format # Bezos Slide Format
@ -31,6 +31,7 @@ Bare content like this
* { "bg_color": [r,g,b,a] } * { "bg_color": [r,g,b,a] }
* Same as deck header * Same as deck header
* Put before the content * Put before the content
* It works
--- ---
{ "bg_image": "assets/sample_bg.jpg" } { "bg_image": "assets/sample_bg.jpg" }
@ -62,3 +63,7 @@ One Word
* Text will go over image * Text will go over image
* Image will stretch to fill * Image will stretch to fill
--- ---
# Hot Reload
* It watches the file and
reloads when it changes
---

@ -13,9 +13,9 @@
#include "control_ui.hpp" #include "control_ui.hpp"
ControlUI::ControlUI(sf::RenderWindow& presenter) : ControlUI::ControlUI(sf::RenderWindow& presenter) :
$presenter(presenter) $presenter(presenter),
$window_size($presenter.getSize())
{ {
$gui.position(0, 0, CONTROL_WIDTH, CONTROL_HEIGHT); $gui.position(0, 0, CONTROL_WIDTH, CONTROL_HEIGHT);
$gui.layout( $gui.layout(
"[status|=%(100,100)current]" "[status|=%(100,100)current]"
@ -28,7 +28,7 @@ void ControlUI::init() {
$gui.set<guecs::Text>(status_id, {L""}); $gui.set<guecs::Text>(status_id, {L""});
auto docs_id = $gui.entity("docs"); auto docs_id = $gui.entity("docs");
$gui.set<guecs::Text>(docs_id, {L"A: win left\nD: win right\nQ: quit"}); $gui.set<guecs::Text>(docs_id, {L"F: fullscreen\nA: win left\nD: win right\nQ: quit"});
auto current = $gui.entity("current"); auto current = $gui.entity("current");
$gui.set<guecs::Rectangle>(current, {}); $gui.set<guecs::Rectangle>(current, {});
@ -68,21 +68,29 @@ void ControlUI::handle_events(sf::RenderWindow& controller, const sf::Event& eve
if(const auto* key = event.getIf<sf::Event::KeyPressed>()) { if(const auto* key = event.getIf<sf::Event::KeyPressed>()) {
auto pos = $presenter.getPosition(); auto pos = $presenter.getPosition();
auto size = $presenter.getSize();
using KEY = sf::Keyboard::Scan; using KEY = sf::Keyboard::Scan;
switch(key->scancode) { switch(key->scancode) {
case KEY::A: { case KEY::A: {
pos.x -= size.x; pos.x -= $window_size.x;
$presenter.setPosition(pos); $presenter.setPosition(pos);
} break; } break;
case KEY::D: { case KEY::D: {
pos.x += int(size.x); pos.x += int($window_size.x);
$presenter.setPosition(pos); $presenter.setPosition(pos);
} break; } break;
case KEY::Q: case KEY::Q:
controller.close(); controller.close();
break; break;
case KEY::F:
if($full_screen) {
$presenter.setSize({$window_size.x/2, $window_size.y/2});
} else {
$presenter.setSize($window_size);
}
$full_screen = !$full_screen;
break;
default: default:
break; break;
} }

@ -5,9 +5,11 @@
#include "slides_ui.hpp" #include "slides_ui.hpp"
struct ControlUI { struct ControlUI {
bool $full_screen = true;
guecs::UI $gui; guecs::UI $gui;
guecs::Text* $status; guecs::Text* $status;
sf::RenderWindow& $presenter; sf::RenderWindow& $presenter;
sf::Vector2u $window_size;
ControlUI(sf::RenderWindow& presenter); ControlUI(sf::RenderWindow& presenter);
void init(); void init();

@ -6,18 +6,60 @@
#include "slides_ui.hpp" #include "slides_ui.hpp"
#include "control_ui.hpp" #include "control_ui.hpp"
#include "parser.hpp" #include "parser.hpp"
#include <filesystem>
#include <chrono>
#include <SFML/System/Clock.hpp>
int main(int argc, char *argv[]) { using namespace std::chrono_literals;
dbc::check(argc >= 2, "USAGE: bezos my_fucking_slides.md");
auto backend = std::make_shared<gui::Backend>(); std::optional<SlidesUI> load_slides(const std::string& input_md, std::shared_ptr<gui::Backend> backend) {
try {
auto data = parse_slides(input_md, [&](nlohmann::json& config) {
backend->set_font(config["font_file"]);
guecs::init(backend.get());
});
auto data = parse_slides(argv[1], [&](nlohmann::json& config) { fmt::println("FONT FILE: {}", backend->$font_file);
backend->set_font(config["font_file"]);
guecs::init(backend.get()); SlidesUI slides(data);
}); slides.init();
return slides;
} catch(...) {
fmt::println("ERROR!");
return std::nullopt;
}
}
struct ChangeDetector {
std::string input_md;
sf::Clock timer{};
std::filesystem::file_time_type last_mod_time = std::filesystem::last_write_time(input_md);
bool check_changed() {
if(timer.getElapsedTime().toDuration() > 500ms) {
try {
auto mod_time = std::filesystem::last_write_time(input_md);
if(last_mod_time < mod_time) {
last_mod_time = mod_time;
return true;
} else {
return false;
}
} catch(const std::filesystem::filesystem_error& err) {
fmt::println("failed to open {}: {}", err.path1().string(), err.what());
timer.restart();
return false;
}
}
return false;
}
};
fmt::println("FONT FILE: {}", backend->$font_file); int main(int argc, char *argv[]) {
dbc::check(argc >= 2, "USAGE: bezos my_fucking_slides.md");
auto& modes = sf::VideoMode::getFullscreenModes(); auto& modes = sf::VideoMode::getFullscreenModes();
auto screen_mode = std::find_if(modes.begin(), modes.end(), [=](const auto& a) -> bool { auto screen_mode = std::find_if(modes.begin(), modes.end(), [=](const auto& a) -> bool {
@ -32,25 +74,26 @@ int main(int argc, char *argv[]) {
presenter.setFramerateLimit(FRAME_LIMIT); presenter.setFramerateLimit(FRAME_LIMIT);
presenter.setVerticalSyncEnabled(VSYNC); presenter.setVerticalSyncEnabled(VSYNC);
SlidesUI slides(data); auto backend = std::make_shared<gui::Backend>();
slides.init();
auto new_slides = load_slides(argv[1], backend);
if(!new_slides) {
fmt::println("ERROR in your .md file");
return 1;
}
SlidesUI slides = *new_slides;
ControlUI control_ui(presenter); ControlUI control_ui(presenter);
control_ui.init(); control_ui.init();
dbc::check(control_ui.$status != nullptr, "bad ptr"); dbc::check(control_ui.$status != nullptr, "bad ptr");
ChangeDetector reloader{argv[1]};
while(controller.isOpen()) { while(controller.isOpen()) {
while (const auto event = presenter.pollEvent()) { while (const auto event = presenter.pollEvent()) {
if(const auto* mouse = event->getIf<sf::Event::MouseButtonPressed>()) { if(event) slides.handle_events(presenter, *event);
sf::Vector2f pos = presenter.mapPixelToCoords(mouse->position);
if(mouse->button == sf::Mouse::Button::Left) {
slides.mouse(pos.x, pos.y, {1 << guecs::ModBit::left});
} else if(mouse->button == sf::Mouse::Button::Right) {
slides.mouse(pos.x, pos.y, {1 << guecs::ModBit::right});
}
}
} }
while (const auto event = controller.pollEvent()) { while (const auto event = controller.pollEvent()) {
@ -62,5 +105,14 @@ int main(int argc, char *argv[]) {
presenter.display(); presenter.display();
controller.display(); controller.display();
if(reloader.check_changed()) {
auto new_slides = load_slides(argv[1], backend);
if(new_slides) {
new_slides->set_slide(slides.$current);
slides = *new_slides;
}
}
} }
} }

@ -139,6 +139,11 @@ void SlidesUI::prev_slide() {
} }
} }
void SlidesUI::set_slide(size_t index) {
$current = index < $deck->slides.size() ? index : 0;
show_slide();
}
void SlidesUI::show_slide() { void SlidesUI::show_slide() {
auto& slide = current(); auto& slide = current();
@ -187,3 +192,15 @@ void SlidesUI::mouse(float x, float y, guecs::Modifiers mods) {
prev_slide(); prev_slide();
} }
} }
void SlidesUI::handle_events(sf::RenderWindow& presenter, const sf::Event& event) {
if(const auto* mev = event.getIf<sf::Event::MouseButtonPressed>()) {
sf::Vector2f pos = presenter.mapPixelToCoords(mev->position);
if(mev->button == sf::Mouse::Button::Left) {
mouse(pos.x, pos.y, {1 << guecs::ModBit::left});
} else if(mev->button == sf::Mouse::Button::Right) {
mouse(pos.x, pos.y, {1 << guecs::ModBit::right});
}
}
}

@ -45,7 +45,9 @@ struct SlidesUI {
void next_slide(); void next_slide();
void prev_slide(); void prev_slide();
void show_slide(); void show_slide();
void set_slide(size_t index);
void render(sf::RenderWindow& window); void render(sf::RenderWindow& window);
void mouse(float x, float y, guecs::Modifiers mods); void mouse(float x, float y, guecs::Modifiers mods);
void set_text(const std::string& name); void set_text(const std::string& name);
void handle_events(sf::RenderWindow& presenter, const sf::Event& event);
}; };

Loading…
Cancel
Save