Can now control the slides from the control window...'cause it controls the slides.

master
Zed A. Shaw 4 weeks ago
parent 1fb3dea874
commit 459ff06eee
  1. 3
      assets/layouts.json
  2. 62
      sample/about-bezos.md
  3. 55
      src/control_ui.cpp
  4. 14
      src/control_ui.hpp
  5. 12
      src/main.cpp
  6. 54
      src/slides_ui.cpp
  7. 12
      src/slides_ui.hpp

@ -29,6 +29,9 @@
"[_|_|_|_|_]",
"[_|_|_|_|_]"
],
"no_title": [
"[*%(300,600)content]"
],
"centered": [
"[=*%(300,400)title|_|_|_|_]",
"[_|_|_]",

@ -1,21 +1,44 @@
{
"title": "How to use Bezos",
"description": "A short presentation on Bezos.",
"description": "The PowerPoint killer for PowerPoint haters like Jeff.",
"font_file": "assets/bold.otf",
"layouts": "assets/layouts.json"
}
===
# Bezos Loves Slides
* My PowerPoint Killer
{
"font_size": 120,
"font_centered": false,
"layout": "no_title"
}
Jeff
Bezos
Loves
PowerPoint
---
# That Fateful Day
* The Deck From Hell
* Jeff Bans PowerPoint
* What Was That Deck?
---
{
"font_size": 120,
"font_centered": false
}
Can We Blame Him?
---
# I Hate PowerPoint Too
* So I made an alternative.
* Markdown Format
* Images, Shaders, soon Video?
* Hot Reload
* Images, and Shaders.
* Not Much Else
---
# Bezos Slide Format
* Just markdown
separated by ---
* Each slide can
have a json header
have a json metadata
header for config
---
# Supported Markdown
* Simple lists with *
@ -25,7 +48,7 @@
Bare content like this
---
# Deck Header
* Right after ===
* Right after ---
* Use {} to configure
* "title"
* "description"
@ -33,7 +56,6 @@ Bare content like this
* "bg_image": "filepath.jpg"
---
{ "bg_color": [55, 20, 10, 255] }
# Slide Color
* { "bg_color": [r,g,b,a] }
* Same as deck header
@ -58,6 +80,7 @@ Bare content like this
"bg_color": [10, 10, 25, 255],
"font_color": [255, 146, 0, 255],
"font_size": 80,
"title_size": 120,
"font_padding": 20
}
# Font Config
@ -67,11 +90,11 @@ Bare content like this
* "X_padding": int
---
{
"font_size": 120,
"font_centered": true,
"layout": "centered"
"font_size": 180,
"layout": "no_title"
}
One Word
Flexible
Layouts
---
# Images
!(assets/sample_bg.jpg)
@ -97,3 +120,20 @@ One Word
* It watches the file and
reloads when it changes
---
# Current Status
* Mostly works for me
* Written in C++ using
my game UI library
* Quick hack POC
* Might Rewrite in Go for
max portability
---
{
"font_size": 240,
"layout": "no_title",
"bg_color": [10, 10, 25, 255],
"font_color": [255, 146, 0, 255]
}
Demo
Time
---

@ -12,8 +12,10 @@
#include "constants.hpp"
#include "control_ui.hpp"
ControlUI::ControlUI(sf::RenderWindow& presenter) :
ControlUI::ControlUI(sf::RenderWindow& presenter, sf::RenderWindow& controller) :
$presenter(presenter),
$controller(controller),
$window_size($presenter.getSize())
{
$gui.position(0, 0, CONTROL_WIDTH, CONTROL_HEIGHT);
@ -23,29 +25,46 @@ ControlUI::ControlUI(sf::RenderWindow& presenter) :
);
}
void ControlUI::config_views(guecs::Entity current, guecs::Entity next) {
// BUG jank ass bullshit, fix this in lel-guecs
auto& cur_cell = $gui.cell_for(current);
$cur_view = std::make_shared<sf::RenderTexture>($presenter.getSize());
$cur_sprite = std::make_shared<sf::Sprite>($cur_view->getTexture());
$cur_sprite->setPosition({float(cur_cell.x), float(cur_cell.y)});
$cur_sprite->setScale({0.3f, 0.3f});
auto& next_cell = $gui.cell_for(next);
$next_view = std::make_shared<sf::RenderTexture>($presenter.getSize());
$next_sprite = std::make_shared<sf::Sprite>($next_view->getTexture());
$next_sprite->setPosition({float(next_cell.x), float(next_cell.y)});
$next_sprite->setScale({0.3f, 0.3f});
}
void ControlUI::init() {
auto status_id = $gui.entity("status");
$gui.set<guecs::Text>(status_id, {L""});
auto docs_id = $gui.entity("docs");
$gui.set<guecs::Text>(docs_id, {L"F: fullscreen\nA: win left\nD: win right\nQ: quit"});
$gui.init();
auto current = $gui.entity("current");
$gui.set<guecs::Rectangle>(current, {});
$gui.set<guecs::Text>(current, {L"Current Slide"});
auto next = $gui.entity("next");
$gui.set<guecs::Rectangle>(next, {});
$gui.set<guecs::Text>(next, {L"Next Slide"});
$gui.init();
config_views(current, next);
// warning! must come after init so the thing is there
$status = $gui.get_if<guecs::Text>(status_id);
dbc::check($status != nullptr, "failed to setup the status text");
}
void ControlUI::render(sf::RenderWindow& window) {
inline void render_slide(sf::RenderTexture& view, Slide& slide) {
view.clear();
slide.render(view);
view.display();
}
void ControlUI::render(sf::RenderWindow& window, SlideDeck& deck) {
dbc::check($status != nullptr, "called render before init?");
auto pos = $presenter.getPosition();
@ -53,16 +72,24 @@ void ControlUI::render(sf::RenderWindow& window) {
$status->update(fmt::format(L"pos={},{}\nsize={},{}",
pos.x, pos.y, size.x, size.y));
window.clear();
window.clear();
$gui.render(window);
render_slide(*$cur_view, deck.current_slide());
window.draw(*$cur_sprite);
/*
render_slide(*$next_view, deck.preview_slide());
window.draw(*$next_sprite);
*/
}
void ControlUI::handle_events(sf::RenderWindow& controller, const sf::Event& event) {
void ControlUI::handle_events(std::shared_ptr<SlidesUI> slides, const sf::Event& event) {
dbc::check($status != nullptr, "handle_events called before init?!");
if(event.is<sf::Event::Closed>()) {
controller.close();
$controller.close();
return;
}
@ -80,19 +107,21 @@ void ControlUI::handle_events(sf::RenderWindow& controller, const sf::Event& eve
$presenter.setPosition(pos);
} break;
case KEY::Q:
controller.close();
$controller.close();
break;
case KEY::F:
if($full_screen) {
$presenter.setSize({$window_size.x/2, $window_size.y/2});
$presenter.setMouseCursorVisible(true);
} else {
$presenter.setSize($window_size);
$presenter.setMouseCursorVisible(false);
}
$full_screen = !$full_screen;
break;
default:
break;
slides->handle_events($controller, event);
}
}
}

@ -9,10 +9,18 @@ struct ControlUI {
guecs::UI $gui;
guecs::Text* $status;
sf::RenderWindow& $presenter;
sf::RenderWindow& $controller;
sf::Vector2u $window_size;
ControlUI(sf::RenderWindow& presenter);
std::shared_ptr<sf::RenderTexture> $cur_view = nullptr;
std::shared_ptr<sf::Sprite> $cur_sprite = nullptr;
std::shared_ptr<sf::RenderTexture> $next_view = nullptr;
std::shared_ptr<sf::Sprite> $next_sprite = nullptr;
ControlUI(sf::RenderWindow& presenter, sf::RenderWindow& controller);
void init();
void render(sf::RenderWindow& window);
void handle_events(sf::RenderWindow& controller, const sf::Event& event);
void render(sf::RenderWindow& window, SlideDeck& deck);
void handle_events(std::shared_ptr<SlidesUI> slides, const sf::Event& event);
void config_views(guecs::Entity current, guecs::Entity next);
};

@ -15,14 +15,14 @@ using namespace std::chrono_literals;
std::shared_ptr<SlidesUI> load_slides(const std::string& input_md, std::shared_ptr<gui::Backend> backend) {
try {
auto data = parse_slides(input_md, [&](nlohmann::json& config) {
auto deck = parse_slides(input_md, [&](nlohmann::json& config) {
backend->set_font(config["font_file"]);
guecs::init(backend.get());
});
fmt::println("FONT FILE: {}", backend->$font_file);
auto slides = std::make_shared<SlidesUI>(data, sf::Vector2u{WINDOW_WIDTH, WINDOW_HEIGHT});
auto slides = std::make_shared<SlidesUI>(deck, sf::Vector2u{WINDOW_WIDTH, WINDOW_HEIGHT});
slides->init();
return slides;
@ -85,7 +85,7 @@ int main(int argc, char *argv[]) {
return 1;
}
ControlUI control_ui(presenter);
ControlUI control_ui(presenter, controller);
control_ui.init();
dbc::check(control_ui.$status != nullptr, "bad ptr");
@ -99,18 +99,18 @@ int main(int argc, char *argv[]) {
}
while (const auto event = controller.pollEvent()) {
if(event) control_ui.handle_events(controller, *event);
if(event) control_ui.handle_events(slides, *event);
}
slides->render(presenter);
control_ui.render(controller);
control_ui.render(controller, *slides->$deck);
presenter.display();
controller.display();
if(slides_reloader.changed() || layout_reloader.changed()) {
// save the current slide
auto current_slide = slides->$current;
auto current_slide = slides->$deck->current;
// load the new one
auto new_slides = load_slides(argv[1], backend);

@ -34,15 +34,19 @@ void Slide::init(lel::Cell& cell, const std::string& layout) {
$gui.position(cell.x, cell.y, cell.w, cell.h);
$gui.layout(layout);
if($gui.contains("title")) {
auto title = $gui.entity("title");
$gui.set<guecs::Text>(title, $title_font);
}
auto content = $gui.entity("content");
$gui.set<guecs::Text>(content, $content_font);
if($config.contains("image")) {
std::string image_name = $config["image"];
auto at_cell = $config.contains("image_cell") ? $gui.entity($config["image_cell"]) : content;
bool stretched = $config.contains("image_stretch") ? $config["image_stretch"].get<bool>() : true;
$gui.set<guecs::Sprite>(at_cell, {image_name, guecs::THEME.PADDING, stretched});
}
@ -74,6 +78,35 @@ void Slide::render(sf::RenderTarget& view) {
// $gui.debug_layout(view);
}
void SlideDeck::set_slide(size_t index) {
current = index < slides.size() ? index : 0;
}
bool SlideDeck::at_end() {
return current >= slides.size() - 1;
}
Slide& SlideDeck::current_slide() {
return slides.at(current);
}
Slide& SlideDeck::preview_slide() {
return slides.at(current + 1);
}
void SlideDeck::next_slide() {
if(current < slides.size() - 1) {
current++;
}
}
void SlideDeck::prev_slide() {
if(current > 0) {
current--;
}
}
SlidesUI::SlidesUI(shared_ptr<SlideDeck> deck, sf::Vector2u size) :
$view_texture{size},
$view_sprite($view_texture.getTexture())
@ -81,7 +114,6 @@ SlidesUI::SlidesUI(shared_ptr<SlideDeck> deck, sf::Vector2u size) :
dbc::check(deck != nullptr, "deck is null");
dbc::check(deck->slides.size() > 0, "slide deck is empy");
$deck = deck;
$current = 0;
configure_layouts();
}
@ -113,31 +145,25 @@ void SlidesUI::init() {
$gui.init();
}
Slide& SlidesUI::current() {
return $deck->slides.at($current);
}
void SlidesUI::next_slide() {
if($current < $deck->slides.size() - 1) {
$current++;
$deck->next_slide();
show_slide();
}
}
void SlidesUI::prev_slide() {
if($current > 0) {
$current--;
$deck->prev_slide();
show_slide();
}
}
void SlidesUI::set_slide(size_t index) {
$current = index < $deck->slides.size() ? index : 0;
$deck->set_slide(index);
show_slide();
}
void SlidesUI::show_slide() {
auto& slide = current();
// THIS NEEDS TO BE DONE FOR ALL SLIDES OR CONTROL CAN'T SHOW NEXT SLIDE
// MOVE TO DECK
auto& slide = $deck->current_slide();
// kind of have to set the background for the whole UI using the slide config
auto& bg = $gui.get<guecs::Background>($gui.MAIN);
@ -185,7 +211,7 @@ void SlidesUI::show_slide() {
void SlidesUI::render(sf::RenderTarget& window) {
$gui.render($view_texture);
auto& slide = current();
auto& slide = $deck->current_slide();
slide.render($view_texture);
$view_texture.display();

@ -32,6 +32,14 @@ using SlideSet = std::vector<Slide>;
struct SlideDeck {
nlohmann::json config;
SlideSet slides;
size_t current = 0;
bool at_end();
Slide& current_slide();
Slide& preview_slide();
void next_slide();
void prev_slide();
void set_slide(size_t index);
};
struct SlidesUI {
@ -41,11 +49,11 @@ struct SlidesUI {
sf::RenderTexture $view_texture;
sf::Sprite $view_sprite;
sf::Clock $clock;
size_t $current = 0;
SlidesUI(std::shared_ptr<SlideDeck> deck, sf::Vector2u size);
void init();
Slide& current();
Slide& current_slide();
void next_slide();
void prev_slide();

Loading…
Cancel
Save