Skip to content

Commit

Permalink
feat: add arg json file, read imgs from same dir
Browse files Browse the repository at this point in the history
  • Loading branch information
Chleba committed Jun 4, 2024
1 parent 0dba89d commit 2fabba9
Show file tree
Hide file tree
Showing 15 changed files with 120 additions and 20 deletions.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes.
6 changes: 4 additions & 2 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub struct App {
pub config: Config,
pub tick_rate: f64,
pub frame_rate: f64,
pub json_slides: String,
pub components: Vec<Box<dyn Component>>,
pub should_quit: bool,
pub should_suspend: bool,
Expand All @@ -24,7 +25,7 @@ pub struct App {
}

impl App {
pub fn new(tick_rate: f64, frame_rate: f64) -> Result<Self> {
pub fn new(tick_rate: f64, frame_rate: f64, json_slides: String) -> Result<Self> {
let title = Title::new();
let slides = Slides::new();
let config = Config::new()?;
Expand All @@ -33,6 +34,7 @@ impl App {
Ok(Self {
tick_rate,
frame_rate,
json_slides,
components: vec![Box::new(title), Box::new(slides)],
should_quit: false,
should_suspend: false,
Expand Down Expand Up @@ -60,7 +62,7 @@ impl App {
}

for component in self.components.iter_mut() {
component.init(tui.size()?)?;
component.init(tui.size()?, self.json_slides.clone())?;
}

loop {
Expand Down
9 changes: 9 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,13 @@ pub struct Cli {
default_value_t = 4.0
)]
pub frame_rate: f64,

#[arg(
short,
long = "json",
value_name = "PATH",
help = "Path to slides JSON file along with images folder",
default_value = ".data/slides.json5"
)]
pub json_slides: String,
}
2 changes: 1 addition & 1 deletion src/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub trait Component {
/// # Returns
///
/// * `Result<()>` - An Ok result or an error.
fn init(&mut self, area: Rect) -> Result<()> {
fn init(&mut self, area: Rect, json_slides: String) -> Result<()> {
Ok(())
}
/// Handle incoming events and produce actions if necessary.
Expand Down
30 changes: 22 additions & 8 deletions src/components/slides.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::io::Read;
use std::path::Path;

use color_eyre::{eyre::Result, owo_colors::OwoColorize};
use ratatui::{
Expand All @@ -20,6 +21,7 @@ use crate::{

pub struct Slides {
action_tx: Option<UnboundedSender<Action>>,
json_slides: String,
slides: Option<SlidesJson>,
slide_index: usize,
slide_count: usize,
Expand All @@ -36,6 +38,7 @@ impl Slides {
pub fn new() -> Self {
Self {
action_tx: None,
json_slides: String::from(""),
slides: None,
slide_index: 0,
slide_count: 0,
Expand All @@ -44,10 +47,11 @@ impl Slides {
}

fn get_json_slides(&mut self) {
let mut f =
std::fs::File::open(".data/slides.json5").expect("Failed to open slides json file");
// let data_dir = crate::utils::get_data_dir();
// let mut f = std::fs::File::open(data_dir.join("slides.json5")).expect("Failed to open slides json file");
let error_string = format!(
"file: '{}' failed to open slides json file",
self.json_slides
);
let mut f = std::fs::File::open(self.json_slides.clone()).expect(&error_string);
let mut f_content = String::new();
f.read_to_string(&mut f_content)
.expect("Failed to read json slides file");
Expand Down Expand Up @@ -131,17 +135,24 @@ impl Slides {
)
}

fn make_slide_items<'a>(slide: &SlideJson) -> Vec<(ReturnSlideWidget<'a>, Option<Rect>)> {
fn make_slide_items<'a>(
slide: &SlideJson,
json_slides: String,
) -> Vec<(ReturnSlideWidget<'a>, Option<Rect>)> {
let mut slide_items = vec![];
for item in &slide.content {
slide_items.push((make_slide_content(item.clone()), item.rect));
slide_items.push((
make_slide_content(item.clone(), json_slides.clone()),
item.rect,
));
}
slide_items
}
}

impl Component for Slides {
fn init(&mut self, area: Rect) -> Result<()> {
fn init(&mut self, area: Rect, json_slides: String) -> Result<()> {
self.json_slides = json_slides;
self.picker.guess_protocol();
self.get_json_slides();
Ok(())
Expand Down Expand Up @@ -178,7 +189,7 @@ impl Component for Slides {

let slide = self.get_slide();

let slide_items = Self::make_slide_items(&slide);
let slide_items = Self::make_slide_items(&slide, self.json_slides.clone());
let title = Self::make_title(&slide);
let block = self.make_block();

Expand All @@ -203,6 +214,9 @@ impl Component for Slides {
let img = StatefulImage::new(None).resize(Resize::Fit(None));
f.render_stateful_widget(img, slide_rect, &mut img_static);
}
ReturnSlideWidget::Block(s) => {
f.render_widget(s, slide_rect);
}
}
}
Ok(())
Expand Down
4 changes: 3 additions & 1 deletion src/enums.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use image::DynamicImage;
use ratatui::{layout::Rect, text::Line, widgets::Paragraph};
use ratatui::{layout::Rect, text::Line, widgets::{Block, Paragraph}};
use serde::{Deserialize, Serialize};
use tui_big_text::BigText;

Expand All @@ -9,6 +9,7 @@ pub enum ReturnSlideWidget<'a> {
BigText(BigText<'a>),
Line(Line<'a>),
Image(DynamicImage),
Block(Block<'a>),
}

#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
Expand All @@ -17,6 +18,7 @@ pub enum SlideContentType {
BigText,
Line,
Image,
Block,
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ async fn tokio_main() -> Result<()> {
initialize_panic_handler()?;

let args = Cli::parse();
let mut app = App::new(args.tick_rate, args.frame_rate)?;
let mut app = App::new(args.tick_rate, args.frame_rate, args.json_slides)?;
app.run().await?;

Ok(())
Expand Down
43 changes: 36 additions & 7 deletions src/slide_builder.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
use std::path::Path;

use crate::enums::{ContentJson, ReturnSlideWidget, SlideContentType, SlideJson};
use color_eyre::owo_colors::colors::css::Beige;
use color_eyre::{eyre::Result, owo_colors::OwoColorize};
use crossterm::terminal::size;
use ratatui::{
layout::Rect, text::Line, widgets::{Block, Paragraph, WidgetRef}
layout::{Alignment, Rect},
prelude::*,
style::Stylize,
text::Line,
widgets::{block::{self, Title}, Block, Borders, Paragraph, WidgetRef},
};
use ratatui_image::{picker:: Picker, Resize, Image, StatefulImage};
use ratatui_image::{picker::Picker, Image, Resize, StatefulImage};
use tui_big_text::BigText;

pub fn get_slide_content_string(slide: ContentJson) -> String {
Expand Down Expand Up @@ -41,17 +47,40 @@ fn make_slide_bigtext<'a>(slide: ContentJson) -> ReturnSlideWidget<'a> {
)
}

pub fn make_slide_image<'a>(slide: ContentJson) -> ReturnSlideWidget<'a> {
fn make_slide_image<'a>(slide: ContentJson, slide_path: String) -> ReturnSlideWidget<'a> {
let f_path = Path::new(&slide_path);
let img_path = f_path.parent().unwrap();
let content = get_slide_content_string(slide);
let dyn_img = image::io::Reader::open(content).unwrap().decode().unwrap();
let dyn_img = image::io::Reader::open(img_path.join(content))
.unwrap()
.decode()
.unwrap();
ReturnSlideWidget::Image(dyn_img)
}

pub fn make_slide_content<'a>(slide_content: ContentJson) -> ReturnSlideWidget<'a> {
fn make_slide_block<'a>(slide: ContentJson) -> ReturnSlideWidget<'a> {
let content = get_slide_content_string(slide);
ReturnSlideWidget::Block(
Block::default()
.borders(Borders::ALL)
.border_style(Style::default().fg(Color::Rgb(100, 100, 100)))
.title(
Title::from(Line::from(vec![content.yellow()]))
.alignment(Alignment::Right)
.position(block::Position::Bottom),
),
)
}

pub fn make_slide_content<'a>(
slide_content: ContentJson,
slide_path: String,
) -> ReturnSlideWidget<'a> {
match slide_content.type_ {
SlideContentType::Paragraph => make_slide_paragraph(slide_content),
SlideContentType::BigText => make_slide_bigtext(slide_content),
SlideContentType::Line => make_slide_line(slide_content),
SlideContentType::Image => make_slide_image(slide_content),
SlideContentType::Image => make_slide_image(slide_content, slide_path),
SlideContentType::Block => make_slide_block(slide_content),
}
}
Binary file added talk_example/images/bomb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added talk_example/images/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added talk_example/images/hex_red.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions talk_example/slides.json5
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"box_size": {
"percent_width": 75,
"percent_height": 65
},

"slides" : [
{
"title": "RATATUI",
"content": [
{
"type": "BigText",
"content": "BIGTEXT",
"rect": { "x": 5, "y": 5, "width": 50, "height": 6 }
},
{
"type": "Paragraph",
"content": "Terminal user interface library",
"rect": { "x": 5, "y": 20, "width": 50, "height": 3 }
},
{
"type": "Image",
"content": "./images/bomb.png",
"rect": { "x": 0, "y": 0, "width": 15, "height": 15 }
},
{
"type": "Image",
"content": "./images/hex_red.png",
"rect": { "x": 40, "y": 30, "width": 20, "height": 20 }
}
]
},
{
"title": ":$ whoami",
"content": [
{
"type": "Line",
"content": "Lukas Chleba",
"rect": { "x": 5, "y": 5, "width": 50, "height": 3 }
}
]
}
]
}

0 comments on commit 2fabba9

Please sign in to comment.