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. 84
      src/main.cpp
  5. 17
      src/slides_ui.cpp
  6. 2
      src/slides_ui.hpp

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

@ -13,9 +13,9 @@
#include "control_ui.hpp"
ControlUI::ControlUI(sf::RenderWindow& presenter) :
$presenter(presenter)
$presenter(presenter),
$window_size($presenter.getSize())
{
$gui.position(0, 0, CONTROL_WIDTH, CONTROL_HEIGHT);
$gui.layout(
"[status|=%(100,100)current]"
@ -28,7 +28,7 @@ void ControlUI::init() {
$gui.set<guecs::Text>(status_id, {L""});
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");
$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>()) {
auto pos = $presenter.getPosition();
auto size = $presenter.getSize();
using KEY = sf::Keyboard::Scan;
switch(key->scancode) {
case KEY::A: {
pos.x -= size.x;
pos.x -= $window_size.x;
$presenter.setPosition(pos);
} break;
case KEY::D: {
pos.x += int(size.x);
pos.x += int($window_size.x);
$presenter.setPosition(pos);
} break;
case KEY::Q:
controller.close();
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:
break;
}

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

@ -6,19 +6,61 @@
#include "slides_ui.hpp"
#include "control_ui.hpp"
#include "parser.hpp"
#include <filesystem>
#include <chrono>
#include <SFML/System/Clock.hpp>
int main(int argc, char *argv[]) {
dbc::check(argc >= 2, "USAGE: bezos my_fucking_slides.md");
using namespace std::chrono_literals;
auto backend = std::make_shared<gui::Backend>();
auto data = parse_slides(argv[1], [&](nlohmann::json& config) {
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());
});
fmt::println("FONT FILE: {}", backend->$font_file);
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;
}
};
int main(int argc, char *argv[]) {
dbc::check(argc >= 2, "USAGE: bezos my_fucking_slides.md");
auto& modes = sf::VideoMode::getFullscreenModes();
auto screen_mode = std::find_if(modes.begin(), modes.end(), [=](const auto& a) -> bool {
return a.size.x == WINDOW_WIDTH && a.size.y == WINDOW_HEIGHT;
@ -32,25 +74,26 @@ int main(int argc, char *argv[]) {
presenter.setFramerateLimit(FRAME_LIMIT);
presenter.setVerticalSyncEnabled(VSYNC);
SlidesUI slides(data);
slides.init();
auto backend = std::make_shared<gui::Backend>();
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);
control_ui.init();
dbc::check(control_ui.$status != nullptr, "bad ptr");
ChangeDetector reloader{argv[1]};
while(controller.isOpen()) {
while (const auto event = presenter.pollEvent()) {
if(const auto* mouse = event->getIf<sf::Event::MouseButtonPressed>()) {
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});
}
}
if(event) slides.handle_events(presenter, *event);
}
while (const auto event = controller.pollEvent()) {
@ -62,5 +105,14 @@ int main(int argc, char *argv[]) {
presenter.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() {
auto& slide = current();
@ -187,3 +192,15 @@ void SlidesUI::mouse(float x, float y, guecs::Modifiers mods) {
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 prev_slide();
void show_slide();
void set_slide(size_t index);
void render(sf::RenderWindow& window);
void mouse(float x, float y, guecs::Modifiers mods);
void set_text(const std::string& name);
void handle_events(sf::RenderWindow& presenter, const sf::Event& event);
};

Loading…
Cancel
Save