From 4860e5a46397980163f52d53ef7cff79ab876004 Mon Sep 17 00:00:00 2001 From: zombkit Date: Sat, 20 Apr 2024 00:34:39 -0700 Subject: [PATCH 01/10] Update Cargo.toml --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index ff54d1d..01b7862 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ratframe" -version = "1.0.3" +version = "1.0.4" authors = ["gold-silver-copper"] edition = "2021" include = ["LICENSE-APACHE", "LICENSE-MIT", "**/*.rs", "Cargo.toml"] From c2226c017dbf8f99ff0fb47d87fd2925a8150041 Mon Sep 17 00:00:00 2001 From: zombkit Date: Sat, 20 Apr 2024 00:44:48 -0700 Subject: [PATCH 02/10] docs --- Cargo.toml | 2 +- src/wasm_runner.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 01b7862..56ea1d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ratframe" -version = "1.0.4" +version = "1.0.5" authors = ["gold-silver-copper"] edition = "2021" include = ["LICENSE-APACHE", "LICENSE-MIT", "**/*.rs", "Cargo.toml"] diff --git a/src/wasm_runner.rs b/src/wasm_runner.rs index 57f583b..62770dd 100644 --- a/src/wasm_runner.rs +++ b/src/wasm_runner.rs @@ -7,10 +7,8 @@ pub trait NewCC { fn new(cc: &eframe::CreationContext<'_>) -> Self; } /// When compiling natively this function generates an eframe::NativeOptions then -/// does eframe::run_native() on your eframe::App -/// -/// NOTE THERE IS ANOTHER FUNCTION CALLED 'wasm_setup' that is exactly the same but for wasm -/// +/// does eframe::run_native() on your eframe::App . +/// NOTE THERE IS ANOTHER FUNCTION CALLED 'wasm_setup' that is exactly the same but for wasm... /// look inside the examples folder and README !!!!! I couldn't figure out how to make docs.rs show it :D #[cfg(not(target_arch = "wasm32"))] pub fn native_setup(eapp: T) -> eframe::Result<()> { From b88b71dd7fefce9dad61e13b745d38fa04da530f Mon Sep 17 00:00:00 2001 From: zombkit Date: Sat, 20 Apr 2024 00:51:28 -0700 Subject: [PATCH 03/10] s --- Cargo.toml | 2 +- examples/demo_web/Cargo.lock | 2 +- src/wasm_runner.rs | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 56ea1d3..2a71a29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ratframe" -version = "1.0.5" +version = "1.0.6" authors = ["gold-silver-copper"] edition = "2021" include = ["LICENSE-APACHE", "LICENSE-MIT", "**/*.rs", "Cargo.toml"] diff --git a/examples/demo_web/Cargo.lock b/examples/demo_web/Cargo.lock index 3f35c1c..c4a1106 100644 --- a/examples/demo_web/Cargo.lock +++ b/examples/demo_web/Cargo.lock @@ -2132,7 +2132,7 @@ dependencies = [ [[package]] name = "ratframe" -version = "1.0.2" +version = "1.0.5" dependencies = [ "eframe", "egui", diff --git a/src/wasm_runner.rs b/src/wasm_runner.rs index 62770dd..861ac16 100644 --- a/src/wasm_runner.rs +++ b/src/wasm_runner.rs @@ -29,6 +29,7 @@ pub fn native_setup(eapp: T) -> eframe::Result /// When compiling for wasm32 this function generates an eframe::WebOptions then /// spawns an async wasm bindgen eframe::WebRunner::new() for your eframe::App +#[cfg_attr(doc, doc(cfg(any(target_arch = "wasm32"))))] #[cfg(any(target_arch = "wasm32", doc))] pub fn wasm_setup(eapp: T) { // Redirect `log` message to `console.log` and friends: From 5b183b52276d7d6e32a266ae9e1f086f09cddef9 Mon Sep 17 00:00:00 2001 From: zombkit Date: Sat, 20 Apr 2024 01:01:57 -0700 Subject: [PATCH 04/10] docs --- Cargo.toml | 2 +- src/lib.rs | 3 ++- src/ratagui_backend.rs | 8 ++++---- src/wasm_runner.rs | 1 - 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2a71a29..0911316 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ratframe" -version = "1.0.6" +version = "1.0.7" authors = ["gold-silver-copper"] edition = "2021" include = ["LICENSE-APACHE", "LICENSE-MIT", "**/*.rs", "Cargo.toml"] diff --git a/src/lib.rs b/src/lib.rs index 00eb3fb..cde8297 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,9 +5,10 @@ mod ratagui_backend; pub use ratagui_backend::RataguiBackend; mod wasm_runner; +pub use wasm_runner::NewCC; #[cfg(not(target_arch = "wasm32"))] pub use wasm_runner::native_setup; -pub use wasm_runner::NewCC; + #[cfg(target_arch = "wasm32")] pub use wasm_runner::wasm_setup; diff --git a/src/ratagui_backend.rs b/src/ratagui_backend.rs index 1eeabeb..a210524 100644 --- a/src/ratagui_backend.rs +++ b/src/ratagui_backend.rs @@ -18,10 +18,10 @@ use ratatui::{ layout::{Rect, Size}, }; -///The RataguiBackend is the widget+backend itself , from which you can make a ratatui terminal -/// then you can do ui.add(terminal.backend_mut()) inside an egui context -/// spawn with RataguiBackend::new() or RataguiBackend::new_with_fonts() -/// see the hello_world_proper example for custom font usage +///The RataguiBackend is the widget+backend itself , from which you can make a ratatui terminal , +/// then you can do ui.add(terminal.backend_mut()) inside an egui context . +/// Spawn with RataguiBackend::new() or RataguiBackend::new_with_fonts() . +/// See the hello_world_proper example for custom font usage #[derive(Debug, Clone, PartialEq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct RataguiBackend { diff --git a/src/wasm_runner.rs b/src/wasm_runner.rs index 861ac16..62770dd 100644 --- a/src/wasm_runner.rs +++ b/src/wasm_runner.rs @@ -29,7 +29,6 @@ pub fn native_setup(eapp: T) -> eframe::Result /// When compiling for wasm32 this function generates an eframe::WebOptions then /// spawns an async wasm bindgen eframe::WebRunner::new() for your eframe::App -#[cfg_attr(doc, doc(cfg(any(target_arch = "wasm32"))))] #[cfg(any(target_arch = "wasm32", doc))] pub fn wasm_setup(eapp: T) { // Redirect `log` message to `console.log` and friends: From 7d76ff305fda1ba334657542d935089038c7da0c Mon Sep 17 00:00:00 2001 From: zombkit Date: Sat, 20 Apr 2024 01:52:08 -0700 Subject: [PATCH 05/10] 2 --- examples/colors_web/Cargo.lock | 2 +- examples/demo_web/Cargo.lock | 2 +- scratch | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 scratch diff --git a/examples/colors_web/Cargo.lock b/examples/colors_web/Cargo.lock index bd61235..8c5c549 100644 --- a/examples/colors_web/Cargo.lock +++ b/examples/colors_web/Cargo.lock @@ -2096,7 +2096,7 @@ dependencies = [ [[package]] name = "ratframe" -version = "1.0.2" +version = "1.0.7" dependencies = [ "eframe", "egui", diff --git a/examples/demo_web/Cargo.lock b/examples/demo_web/Cargo.lock index c4a1106..7f84725 100644 --- a/examples/demo_web/Cargo.lock +++ b/examples/demo_web/Cargo.lock @@ -2132,7 +2132,7 @@ dependencies = [ [[package]] name = "ratframe" -version = "1.0.5" +version = "1.0.7" dependencies = [ "eframe", "egui", diff --git a/scratch b/scratch new file mode 100644 index 0000000..36b5e9d --- /dev/null +++ b/scratch @@ -0,0 +1,8 @@ +Hello everyone ! I present to you my newest crate - ratatui_egui_wasm . +It allows you to create Terminal User Interfaces with ratatui inside of EGUI , and is wasm compatible +Previously I had made bevy_ratatui , but it was not very good , now I created a new backend for ratatui which uses egui. +Thus this new crate supercedes my old bevy_ratatui crate , since now you can use bevy_egui + ratatui_egui_wasm to get a much better experience +Plus performance is like 100x times better :D +Check out a web demo here: https://gold-silver-copper.github.io/ +(use the h j k l t keys to interact) +You can find the repository here - https://github.com/gold-silver-copper/ratatui_egui_wasm From e05e850202117e075dc607ee778bd5e9a617dc0c Mon Sep 17 00:00:00 2001 From: zombkit Date: Sat, 20 Apr 2024 03:34:15 -0700 Subject: [PATCH 06/10] Update Cargo.lock --- Cargo.lock | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 805e0ca..ad2eff4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2135,13 +2135,14 @@ dependencies = [ [[package]] name = "ratframe" -version = "1.0.2" +version = "1.0.7" dependencies = [ "argh", "eframe", "egui", "env_logger", "itertools", + "log", "once_cell", "rand", "ratatui", From 30451d83c5fdb3e93ca0ab2439443e37032ccff5 Mon Sep 17 00:00:00 2001 From: zombkit Date: Sat, 20 Apr 2024 03:42:19 -0700 Subject: [PATCH 07/10] h --- examples/hello_world_web/Cargo.lock | 2 +- examples/hello_world_web/src/main.rs | 61 +++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/examples/hello_world_web/Cargo.lock b/examples/hello_world_web/Cargo.lock index fb37c7f..3724c0a 100644 --- a/examples/hello_world_web/Cargo.lock +++ b/examples/hello_world_web/Cargo.lock @@ -2095,7 +2095,7 @@ dependencies = [ [[package]] name = "ratframe" -version = "1.0.2" +version = "1.0.7" dependencies = [ "eframe", "egui", diff --git a/examples/hello_world_web/src/main.rs b/examples/hello_world_web/src/main.rs index 42df5ce..ff7904b 100644 --- a/examples/hello_world_web/src/main.rs +++ b/examples/hello_world_web/src/main.rs @@ -39,8 +39,18 @@ impl Default for HelloApp { impl NewCC for HelloApp { /// Called once before the first frame. fn new(cc: &eframe::CreationContext<'_>) -> Self { - // setup_custom_fonts(&cc.egui_ctx); - Default::default() + setup_custom_fonts(&cc.egui_ctx); + //Creating the Ratatui backend/ Egui widget here + let backend = RataguiBackend::new_with_fonts( + 100, + 100, + "Regular".into(), + "Bold".into(), + "Oblique".into(), + "BoldOblique".into(), + ); + let mut terminal = Terminal::new(backend).unwrap(); + Self { terminal: terminal } } } @@ -69,3 +79,50 @@ impl eframe::App for HelloApp { }); } } + +fn setup_custom_fonts(ctx: &egui::Context) { + // Start with the default fonts (we will be adding to them rather than replacing them). + let mut fonts = egui::FontDefinitions::default(); + + // Install my own font (maybe supporting non-latin characters). + // .ttf and .otf files supported. + fonts.font_data.insert( + "Regular".to_owned(), + egui::FontData::from_static(include_bytes!("../../../assets/fonts/Iosevka-Regular.ttf")), + ); + fonts.families.insert( + egui::FontFamily::Name("Regular".into()), + vec!["Regular".to_owned()], + ); + fonts.font_data.insert( + "Bold".to_owned(), + egui::FontData::from_static(include_bytes!("../../../assets/fonts/Iosevka-Bold.ttf")), + ); + fonts.families.insert( + egui::FontFamily::Name("Bold".into()), + vec!["Bold".to_owned()], + ); + + fonts.font_data.insert( + "Oblique".to_owned(), + egui::FontData::from_static(include_bytes!("../../../assets/fonts/Iosevka-Oblique.ttf")), + ); + fonts.families.insert( + egui::FontFamily::Name("Oblique".into()), + vec!["Oblique".to_owned()], + ); + + fonts.font_data.insert( + "BoldOblique".to_owned(), + egui::FontData::from_static(include_bytes!( + "../../../assets/fonts/Iosevka-BoldOblique.ttf" + )), + ); + fonts.families.insert( + egui::FontFamily::Name("BoldOblique".into()), + vec!["BoldOblique".to_owned()], + ); + + // Tell egui to use these fonts: + ctx.set_fonts(fonts); +} From 429265213574e4d840586aef717a929e9dad0a3c Mon Sep 17 00:00:00 2001 From: zombkit Date: Sat, 20 Apr 2024 03:52:10 -0700 Subject: [PATCH 08/10] more examples time --- examples/barchart_web/Cargo.toml | 50 +++++++++++ examples/barchart_web/index.html | 95 +++++++++++++++++++++ examples/barchart_web/src/main.rs | 128 ++++++++++++++++++++++++++++ examples/hello_world_web/index.html | 46 +--------- 4 files changed, 274 insertions(+), 45 deletions(-) create mode 100644 examples/barchart_web/Cargo.toml create mode 100644 examples/barchart_web/index.html create mode 100644 examples/barchart_web/src/main.rs diff --git a/examples/barchart_web/Cargo.toml b/examples/barchart_web/Cargo.toml new file mode 100644 index 0000000..d1dd88e --- /dev/null +++ b/examples/barchart_web/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "colors" +version = "1.0.2" +authors = ["gold-silver-copper"] +edition = "2021" +include = ["LICENSE-APACHE", "LICENSE-MIT", "**/*.rs", "Cargo.toml"] +rust-version = "1.76" + +[package.metadata.docs.rs] +all-features = true +targets = ["x86_64-unknown-linux-gnu", "wasm32-unknown-unknown"] + + +[dependencies] +ratatui = { version = "0.26.1", default-features = false } +egui = "0.27.0" +eframe = { version = "0.27.0", default-features = false, features = [ + "accesskit", # Make egui comptaible with screen readers. NOTE: adds a lot of dependencies. + "default_fonts", # Embed the default egui fonts. + "glow", # Use the glow rendering backend. Alternative: "wgpu". + "persistence", # Enable restoring app state when restarting the app. +] } +ratframe = { path = "../../" } + +# native: +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +env_logger = "0.10" + +# web: +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-bindgen-futures = "0.4" +log = "0.4" + +[profile.release] +opt-level = 2 # fast and small wasm + +# Optimize all dependencies even in debug builds: +[profile.dev.package."*"] +opt-level = 2 + + +[patch.crates-io] + +# If you want to use the bleeding edge version of egui and eframe: +# egui = { git = "https://github.com/emilk/egui", branch = "master" } +# eframe = { git = "https://github.com/emilk/egui", branch = "master" } + +# If you fork https://github.com/emilk/egui you can test with: +# egui = { path = "../egui/crates/egui" } +# eframe = { path = "../egui/crates/eframe" } diff --git a/examples/barchart_web/index.html b/examples/barchart_web/index.html new file mode 100644 index 0000000..281f686 --- /dev/null +++ b/examples/barchart_web/index.html @@ -0,0 +1,95 @@ + + + + + + + + + + hello world + + + + + + + + + + + + + + + + + + + + diff --git a/examples/barchart_web/src/main.rs b/examples/barchart_web/src/main.rs new file mode 100644 index 0000000..ff7904b --- /dev/null +++ b/examples/barchart_web/src/main.rs @@ -0,0 +1,128 @@ +use ratatui::{ + prelude::{Stylize, Terminal}, + widgets::Paragraph, +}; +use ratframe::RataguiBackend; + +use ratframe::NewCC; + +#[cfg(not(target_arch = "wasm32"))] +use ratframe::native_setup; + +#[cfg(target_arch = "wasm32")] +use ratframe::wasm_setup; + +// When compiling to web using trunk: +#[cfg(target_arch = "wasm32")] +fn main() { + wasm_setup(HelloApp::default()); +} +// When compiling natively: +#[cfg(not(target_arch = "wasm32"))] +fn main() -> eframe::Result<()> { + native_setup(HelloApp::default()) +} +pub struct HelloApp { + terminal: Terminal, +} + +//l +impl Default for HelloApp { + fn default() -> Self { + //Creating the Ratatui backend/ Egui widget here + let backend = RataguiBackend::new(100, 100); + let mut terminal = Terminal::new(backend).unwrap(); + Self { terminal: terminal } + } +} + +impl NewCC for HelloApp { + /// Called once before the first frame. + fn new(cc: &eframe::CreationContext<'_>) -> Self { + setup_custom_fonts(&cc.egui_ctx); + //Creating the Ratatui backend/ Egui widget here + let backend = RataguiBackend::new_with_fonts( + 100, + 100, + "Regular".into(), + "Bold".into(), + "Oblique".into(), + "BoldOblique".into(), + ); + let mut terminal = Terminal::new(backend).unwrap(); + Self { terminal: terminal } + } +} + +impl eframe::App for HelloApp { + /// Called each time the UI needs repainting, which may be many times per second. + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + //call repaint here so that app runs continuously, remove if you dont need that + ctx.request_repaint(); + self.terminal + .draw(|frame| { + let area = frame.size(); + frame.render_widget(Paragraph::new("Hello Rataguiii").white().on_blue(), area); + }) + .expect("epic fail"); + + egui::CentralPanel::default().show(ctx, |ui| { + ui.add(self.terminal.backend_mut()); + + if ui.input(|i| i.key_released(egui::Key::Q)) { + panic!("HAVE A NICE WEEK"); + } + if ui.input(|i| i.key_released(egui::Key::T)) { + () + } + //KeyCode::Char(c) => app.on_key(c), + }); + } +} + +fn setup_custom_fonts(ctx: &egui::Context) { + // Start with the default fonts (we will be adding to them rather than replacing them). + let mut fonts = egui::FontDefinitions::default(); + + // Install my own font (maybe supporting non-latin characters). + // .ttf and .otf files supported. + fonts.font_data.insert( + "Regular".to_owned(), + egui::FontData::from_static(include_bytes!("../../../assets/fonts/Iosevka-Regular.ttf")), + ); + fonts.families.insert( + egui::FontFamily::Name("Regular".into()), + vec!["Regular".to_owned()], + ); + fonts.font_data.insert( + "Bold".to_owned(), + egui::FontData::from_static(include_bytes!("../../../assets/fonts/Iosevka-Bold.ttf")), + ); + fonts.families.insert( + egui::FontFamily::Name("Bold".into()), + vec!["Bold".to_owned()], + ); + + fonts.font_data.insert( + "Oblique".to_owned(), + egui::FontData::from_static(include_bytes!("../../../assets/fonts/Iosevka-Oblique.ttf")), + ); + fonts.families.insert( + egui::FontFamily::Name("Oblique".into()), + vec!["Oblique".to_owned()], + ); + + fonts.font_data.insert( + "BoldOblique".to_owned(), + egui::FontData::from_static(include_bytes!( + "../../../assets/fonts/Iosevka-BoldOblique.ttf" + )), + ); + fonts.families.insert( + egui::FontFamily::Name("BoldOblique".into()), + vec!["BoldOblique".to_owned()], + ); + + // Tell egui to use these fonts: + ctx.set_fonts(fonts); +} diff --git a/examples/hello_world_web/index.html b/examples/hello_world_web/index.html index f67224f..281f686 100644 --- a/examples/hello_world_web/index.html +++ b/examples/hello_world_web/index.html @@ -10,7 +10,7 @@ - gold silver copper + hello world @@ -82,36 +82,6 @@ font-family: Ubuntu-Light, Helvetica, sans-serif; text-align: center; } - - /* ---------------------------------------------- */ - /* Loading animation from https://loading.io/css/ */ - .lds-dual-ring { - display: inline-block; - width: 24px; - height: 24px; - } - - .lds-dual-ring:after { - content: " "; - display: block; - width: 24px; - height: 24px; - margin: 0px; - border-radius: 50%; - border: 3px solid #fff; - border-color: #fff transparent #fff transparent; - animation: lds-dual-ring 1.2s linear infinite; - } - - @keyframes lds-dual-ring { - 0% { - transform: rotate(0deg); - } - - 100% { - transform: rotate(360deg); - } - } @@ -119,20 +89,6 @@ - - - - From 0d1ccdce2915d719709c4bf71269f5e5cffe5115 Mon Sep 17 00:00:00 2001 From: zombkit Date: Sat, 20 Apr 2024 05:10:38 -0700 Subject: [PATCH 09/10] weeee --- Cargo.lock | 2 +- Cargo.toml | 2 +- examples/barchart_web/Cargo.toml | 2 +- examples/barchart_web/src/main.rs | 264 +++++++++++++++++++++++++-- examples/demo_web/Cargo.lock | 2 +- examples/hello_world_web/Cargo.toml | 2 +- examples/hello_world_web/src/main.rs | 4 +- 7 files changed, 259 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ad2eff4..dd26598 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2135,7 +2135,7 @@ dependencies = [ [[package]] name = "ratframe" -version = "1.0.7" +version = "1.0.8" dependencies = [ "argh", "eframe", diff --git a/Cargo.toml b/Cargo.toml index 0911316..425e567 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ratframe" -version = "1.0.7" +version = "1.0.8" authors = ["gold-silver-copper"] edition = "2021" include = ["LICENSE-APACHE", "LICENSE-MIT", "**/*.rs", "Cargo.toml"] diff --git a/examples/barchart_web/Cargo.toml b/examples/barchart_web/Cargo.toml index d1dd88e..d76498b 100644 --- a/examples/barchart_web/Cargo.toml +++ b/examples/barchart_web/Cargo.toml @@ -21,7 +21,7 @@ eframe = { version = "0.27.0", default-features = false, features = [ "persistence", # Enable restoring app state when restarting the app. ] } ratframe = { path = "../../" } - +web-time = "1" # native: [target.'cfg(not(target_arch = "wasm32"))'.dependencies] env_logger = "0.10" diff --git a/examples/barchart_web/src/main.rs b/examples/barchart_web/src/main.rs index ff7904b..1d0d9c3 100644 --- a/examples/barchart_web/src/main.rs +++ b/examples/barchart_web/src/main.rs @@ -1,8 +1,9 @@ use ratatui::{ - prelude::{Stylize, Terminal}, - widgets::Paragraph, + prelude::*, + widgets::{Bar, BarChart, BarGroup, Block, Borders, Paragraph}, }; use ratframe::RataguiBackend; +use web_time::{Duration, Instant}; use ratframe::NewCC; @@ -24,6 +25,9 @@ fn main() -> eframe::Result<()> { } pub struct HelloApp { terminal: Terminal, + tick_rate: Duration, + app: App<'static>, + last_tick: Instant, } //l @@ -32,7 +36,16 @@ impl Default for HelloApp { //Creating the Ratatui backend/ Egui widget here let backend = RataguiBackend::new(100, 100); let mut terminal = Terminal::new(backend).unwrap(); - Self { terminal: terminal } + // create app and run it + let tick_rate = Duration::from_millis(250); + let app = App::new(); + let mut last_tick = Instant::now(); + Self { + terminal, + tick_rate, + app, + last_tick, + } } } @@ -41,7 +54,7 @@ impl NewCC for HelloApp { fn new(cc: &eframe::CreationContext<'_>) -> Self { setup_custom_fonts(&cc.egui_ctx); //Creating the Ratatui backend/ Egui widget here - let backend = RataguiBackend::new_with_fonts( + let mut backend = RataguiBackend::new_with_fonts( 100, 100, "Regular".into(), @@ -49,8 +62,19 @@ impl NewCC for HelloApp { "Oblique".into(), "BoldOblique".into(), ); + backend.set_font_size(30); let mut terminal = Terminal::new(backend).unwrap(); - Self { terminal: terminal } + + // create app and run it + let tick_rate = Duration::from_millis(250); + let app = App::new(); + let mut last_tick = Instant::now(); + Self { + terminal, + tick_rate, + app, + last_tick, + } } } @@ -59,13 +83,12 @@ impl eframe::App for HelloApp { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { //call repaint here so that app runs continuously, remove if you dont need that ctx.request_repaint(); - self.terminal - .draw(|frame| { - let area = frame.size(); - frame.render_widget(Paragraph::new("Hello Rataguiii").white().on_blue(), area); - }) - .expect("epic fail"); - + self.terminal.draw(|f| ui(f, &self.app)).unwrap(); + let timeout = self.tick_rate.saturating_sub(self.last_tick.elapsed()); + if self.last_tick.elapsed() >= self.tick_rate { + self.app.on_tick(); + self.last_tick = Instant::now(); + } egui::CentralPanel::default().show(ctx, |ui| { ui.add(self.terminal.backend_mut()); @@ -126,3 +149,220 @@ fn setup_custom_fonts(ctx: &egui::Context) { // Tell egui to use these fonts: ctx.set_fonts(fonts); } + +struct Company<'a> { + revenue: [u64; 4], + label: &'a str, + bar_style: Style, +} + +struct App<'a> { + data: Vec<(&'a str, u64)>, + months: [&'a str; 4], + companies: [Company<'a>; 3], +} + +const TOTAL_REVENUE: &str = "Total Revenue"; + +impl<'a> App<'a> { + fn new() -> Self { + App { + data: vec![ + ("B1", 9), + ("B2", 12), + ("B3", 5), + ("B4", 8), + ("B5", 2), + ("B6", 4), + ("B7", 5), + ("B8", 9), + ("B9", 14), + ("B10", 15), + ("B11", 1), + ("B12", 0), + ("B13", 4), + ("B14", 6), + ("B15", 4), + ("B16", 6), + ("B17", 4), + ("B18", 7), + ("B19", 13), + ("B20", 8), + ("B21", 11), + ("B22", 9), + ("B23", 3), + ("B24", 5), + ], + companies: [ + Company { + label: "Comp.A", + revenue: [9500, 12500, 5300, 8500], + bar_style: Style::default().fg(Color::Green), + }, + Company { + label: "Comp.B", + revenue: [1500, 2500, 3000, 500], + bar_style: Style::default().fg(Color::Yellow), + }, + Company { + label: "Comp.C", + revenue: [10500, 10600, 9000, 4200], + bar_style: Style::default().fg(Color::White), + }, + ], + months: ["Mars", "Apr", "May", "Jun"], + } + } + + fn on_tick(&mut self) { + let value = self.data.pop().unwrap(); + self.data.insert(0, value); + } +} + +fn ui(frame: &mut Frame, app: &App) { + let vertical = Layout::vertical([Constraint::Ratio(1, 3), Constraint::Ratio(2, 3)]); + let horizontal = Layout::horizontal([Constraint::Percentage(50), Constraint::Percentage(50)]); + let [top, bottom] = vertical.areas(frame.size()); + let [left, right] = horizontal.areas(bottom); + + let barchart = BarChart::default() + .block(Block::default().title("Data1").borders(Borders::ALL)) + .data(&app.data) + .bar_width(9) + .bar_style(Style::default().fg(Color::Yellow)) + .value_style(Style::default().fg(Color::Black).bg(Color::Yellow)); + + frame.render_widget(barchart, top); + draw_bar_with_group_labels(frame, app, left); + draw_horizontal_bars(frame, app, right); +} + +#[allow(clippy::cast_precision_loss)] +fn create_groups<'a>(app: &'a App, combine_values_and_labels: bool) -> Vec> { + app.months + .iter() + .enumerate() + .map(|(i, &month)| { + let bars: Vec = app + .companies + .iter() + .map(|c| { + let mut bar = Bar::default() + .value(c.revenue[i]) + .style(c.bar_style) + .value_style( + Style::default() + .bg(c.bar_style.fg.unwrap()) + .fg(Color::Black), + ); + + if combine_values_and_labels { + bar = bar.text_value(format!( + "{} ({:.1} M)", + c.label, + (c.revenue[i] as f64) / 1000. + )); + } else { + bar = bar + .text_value(format!("{:.1}", (c.revenue[i] as f64) / 1000.)) + .label(c.label.into()); + } + bar + }) + .collect(); + BarGroup::default() + .label(Line::from(month).centered()) + .bars(&bars) + }) + .collect() +} + +#[allow(clippy::cast_possible_truncation)] +fn draw_bar_with_group_labels(f: &mut Frame, app: &App, area: Rect) { + const LEGEND_HEIGHT: u16 = 6; + + let groups = create_groups(app, false); + + let mut barchart = BarChart::default() + .block(Block::default().title("Data1").borders(Borders::ALL)) + .bar_width(7) + .group_gap(3); + + for group in groups { + barchart = barchart.data(group); + } + + f.render_widget(barchart, area); + + if area.height >= LEGEND_HEIGHT && area.width >= TOTAL_REVENUE.len() as u16 + 2 { + let legend_width = TOTAL_REVENUE.len() as u16 + 2; + let legend_area = Rect { + height: LEGEND_HEIGHT, + width: legend_width, + y: area.y, + x: area.right() - legend_width, + }; + draw_legend(f, legend_area); + } +} + +#[allow(clippy::cast_possible_truncation)] +fn draw_horizontal_bars(f: &mut Frame, app: &App, area: Rect) { + const LEGEND_HEIGHT: u16 = 6; + + let groups = create_groups(app, true); + + let mut barchart = BarChart::default() + .block(Block::default().title("Data1").borders(Borders::ALL)) + .bar_width(1) + .group_gap(1) + .bar_gap(0) + .direction(Direction::Horizontal); + + for group in groups { + barchart = barchart.data(group); + } + + f.render_widget(barchart, area); + + if area.height >= LEGEND_HEIGHT && area.width >= TOTAL_REVENUE.len() as u16 + 2 { + let legend_width = TOTAL_REVENUE.len() as u16 + 2; + let legend_area = Rect { + height: LEGEND_HEIGHT, + width: legend_width, + y: area.y, + x: area.right() - legend_width, + }; + draw_legend(f, legend_area); + } +} + +fn draw_legend(f: &mut Frame, area: Rect) { + let text = vec![ + Line::from(Span::styled( + TOTAL_REVENUE, + Style::default() + .add_modifier(Modifier::BOLD) + .fg(Color::White), + )), + Line::from(Span::styled( + "- Company A", + Style::default().fg(Color::Green), + )), + Line::from(Span::styled( + "- Company B", + Style::default().fg(Color::Yellow), + )), + Line::from(vec![Span::styled( + "- Company C", + Style::default().fg(Color::White), + )]), + ]; + + let block = Block::default() + .borders(Borders::ALL) + .style(Style::default().fg(Color::White)); + let paragraph = Paragraph::new(text).block(block); + f.render_widget(paragraph, area); +} diff --git a/examples/demo_web/Cargo.lock b/examples/demo_web/Cargo.lock index 7f84725..e2c99b7 100644 --- a/examples/demo_web/Cargo.lock +++ b/examples/demo_web/Cargo.lock @@ -2132,7 +2132,7 @@ dependencies = [ [[package]] name = "ratframe" -version = "1.0.7" +version = "1.0.8" dependencies = [ "eframe", "egui", diff --git a/examples/hello_world_web/Cargo.toml b/examples/hello_world_web/Cargo.toml index d1dd88e..d76498b 100644 --- a/examples/hello_world_web/Cargo.toml +++ b/examples/hello_world_web/Cargo.toml @@ -21,7 +21,7 @@ eframe = { version = "0.27.0", default-features = false, features = [ "persistence", # Enable restoring app state when restarting the app. ] } ratframe = { path = "../../" } - +web-time = "1" # native: [target.'cfg(not(target_arch = "wasm32"))'.dependencies] env_logger = "0.10" diff --git a/examples/hello_world_web/src/main.rs b/examples/hello_world_web/src/main.rs index ff7904b..b075d87 100644 --- a/examples/hello_world_web/src/main.rs +++ b/examples/hello_world_web/src/main.rs @@ -2,9 +2,9 @@ use ratatui::{ prelude::{Stylize, Terminal}, widgets::Paragraph, }; -use ratframe::RataguiBackend; - use ratframe::NewCC; +use ratframe::RataguiBackend; +use web_time::{Duration, Instant}; #[cfg(not(target_arch = "wasm32"))] use ratframe::native_setup; From b17697c3c3e70030cf5d8a30ac29fa29a74d57d9 Mon Sep 17 00:00:00 2001 From: zombkit Date: Sat, 20 Apr 2024 05:11:16 -0700 Subject: [PATCH 10/10] Update main.rs --- examples/barchart_web/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/barchart_web/src/main.rs b/examples/barchart_web/src/main.rs index 1d0d9c3..dc0d1d5 100644 --- a/examples/barchart_web/src/main.rs +++ b/examples/barchart_web/src/main.rs @@ -23,6 +23,7 @@ fn main() { fn main() -> eframe::Result<()> { native_setup(HelloApp::default()) } + pub struct HelloApp { terminal: Terminal, tick_rate: Duration,