From cc207fbf8c670637170db40da6058ff1cac7e8af Mon Sep 17 00:00:00 2001 From: Jonathan Johnson Date: Thu, 11 Jan 2024 20:52:40 -0800 Subject: [PATCH] Added optional plotters integration Closes #133 The real work was done in Kludgine. --- CHANGELOG.md | 6 +++ Cargo.lock | 104 ++++++++++++++++++++++++------------------- Cargo.toml | 6 +++ examples/plotters.rs | 49 ++++++++++++++++++++ examples/tilemap.rs | 2 +- src/graphics.rs | 15 ++++++- src/window.rs | 2 +- 7 files changed, 136 insertions(+), 48 deletions(-) create mode 100644 examples/plotters.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index b3b3461..b49f26c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -199,6 +199,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 This type does not prevent redraws from being performed due to the operating system or other threads requeseting them. +- A new feature `plotters` enables integration with the excellent + [plotters][plotters] crate. `Graphics::as_plot_area()` is a new function that + returns a `plotters::DrawingArea` that can be used to draw any plot that the + `plotters` crate supports. + +[plotters]: https://github.com/plotters-rs/plotters [99]: https://github.com/khonsulabs/cushy/issues/99 [120]: https://github.com/khonsulabs/cushy/issues/120 diff --git a/Cargo.lock b/Cargo.lock index 4203424..717ba3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -262,9 +262,9 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] name = "block-sys" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd7cf50912cddc06dc5ea7c08c5e81c1b2c842a70d19def1848d54c586fed92" +checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7" dependencies = [ "objc-sys", ] @@ -431,14 +431,14 @@ dependencies = [ [[package]] name = "console" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ "encode_unicode", "lazy_static", "libc", - "windows-sys 0.45.0", + "windows-sys 0.52.0", ] [[package]] @@ -526,34 +526,28 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.17" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.18" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crunchy" @@ -582,6 +576,7 @@ dependencies = [ "kempt", "kludgine", "palette", + "plotters", "png", "pollster", "rand", @@ -876,9 +871,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "js-sys", @@ -1187,7 +1182,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kludgine" version = "0.7.0" -source = "git+https://github.com/khonsulabs/kludgine#8017775228d22b5efce6d6b7a89e81dfc9b25961" +source = "git+https://github.com/khonsulabs/kludgine#70d9a0df83e8d49894a1b7611385047e9ce23739" dependencies = [ "ahash", "alot", @@ -1201,6 +1196,8 @@ dependencies = [ "justjson", "lyon_tessellation", "palette", + "plotters", + "plotters-backend", "pollster", "smallvec", "unicode-bidi", @@ -1221,9 +1218,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libloading" @@ -1558,18 +1555,18 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1789,6 +1786,24 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +[[package]] +name = "plotters" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +dependencies = [ + "num-traits", + "plotters-backend", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" + [[package]] name = "png" version = "0.17.10" @@ -1846,11 +1861,10 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" +checksum = "6b2685dd208a3771337d8d386a89840f0f43cd68be8dae90a5f8c2384effc9cd" dependencies = [ - "toml_datetime", "toml_edit", ] @@ -1867,9 +1881,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.75" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] @@ -2182,18 +2196,18 @@ checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" [[package]] name = "serde" -version = "1.0.194" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.194" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", @@ -2360,9 +2374,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -2450,15 +2464,15 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ "indexmap", "toml_datetime", @@ -3194,9 +3208,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winit" -version = "0.29.8" +version = "0.29.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc1a7ae1076890701c7dd71ea35b2aebaf9aeb7b8868ac2d33b1c7e8ef93c00" +checksum = "c2376dab13e09c01ad8b679f0dbc7038af4ec43d9a91344338e37bd686481550" dependencies = [ "ahash", "android-activity", @@ -3242,9 +3256,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.5.32" +version = "0.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8434aeec7b290e8da5c3f0d628cb0eac6cabcb31d14bb74f779a08109a5914d6" +checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 0e6e906..0ce8a4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ rust-version = "1.70.0" default = ["tracing-output", "roboto-flex"] tracing-output = ["dep:tracing-subscriber"] roboto-flex = [] +plotters = ["dep:plotters", "kludgine/plotters"] [dependencies] # kludgine = { version = "0.7.0", features = ["app"] } @@ -42,6 +43,7 @@ unicode-segmentation = "1.10.1" pollster = "0.3.0" png = "0.17.10" image = { version = "0.24.7", features = ["png"] } +plotters = { version = "0.3.5", default-features = false, optional = true } # [patch.crates-io] @@ -64,6 +66,10 @@ opt-level = 2 [dev-dependencies] rand = "0.8.5" +[[example]] +name = "plotters" +required-features = ["plotters"] + [profile.release] # debug = true # opt-level = "s" diff --git a/examples/plotters.rs b/examples/plotters.rs new file mode 100644 index 0000000..2c495fe --- /dev/null +++ b/examples/plotters.rs @@ -0,0 +1,49 @@ +use cushy::value::{Dynamic, Source}; +use cushy::widget::MakeWidget; +use cushy::widgets::slider::Slidable; +use cushy::widgets::Canvas; +use cushy::Run; +use plotters::prelude::*; + +// This is copied from the sierpinski.rs example in the plotters repository. +// This just demonstrates that any `plotters` code that renders to a +// `DrawingArea` can be used with a `Canvas`. +pub fn sierpinski_carpet( + depth: u32, + drawing_area: &DrawingArea, +) -> Result<(), Box> +where + A: DrawingBackend, + A::ErrorType: 'static, +{ + if depth > 0 { + let sub_areas = drawing_area.split_evenly((3, 3)); + for (idx, sub_area) in (0..).zip(sub_areas.iter()) { + if idx != 4 { + sub_area.fill(&BLUE)?; + sierpinski_carpet(depth - 1, sub_area)?; + } else { + sub_area.fill(&WHITE)?; + } + } + } + Ok(()) +} + +fn main() -> cushy::Result<()> { + let depth = Dynamic::new(1); + + "Depth" + .and(depth.clone().slider_between(1, 5)) + .and( + Canvas::new({ + move |context| { + let depth = depth.get_tracking_redraw(context); + sierpinski_carpet(depth, &context.gfx.as_plot_area()).unwrap(); + } + }) + .expand(), + ) + .into_rows() + .run() +} diff --git a/examples/tilemap.rs b/examples/tilemap.rs index b01f620..93f7f13 100644 --- a/examples/tilemap.rs +++ b/examples/tilemap.rs @@ -5,7 +5,7 @@ use std::time::Duration; use cushy::figures::units::Px; use cushy::figures::{Point, Rect, Size}; use cushy::kludgine::app::winit::keyboard::Key; -use cushy::kludgine::render::Renderer; +use cushy::kludgine::drawing::Renderer; use cushy::kludgine::shapes::Shape; use cushy::kludgine::tilemap::{ DebugGrid, Object, ObjectLayer, TileArray, TileKind, TileMapFocus, TILE_SIZE, diff --git a/src/graphics.rs b/src/graphics.rs index 81fc3e5..28c0968 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -6,7 +6,7 @@ use figures::{ self, Fraction, IntoSigned, IntoUnsigned, Point, Rect, ScreenScale, ScreenUnit, Size, Zero, }; use kludgine::cosmic_text::FamilyOwned; -use kludgine::render::Renderer; +use kludgine::drawing::Renderer; use kludgine::shapes::Shape; use kludgine::text::{MeasuredText, Text, TextOrigin}; use kludgine::{ @@ -303,6 +303,19 @@ impl<'clip, 'gfx, 'pass> Graphics<'clip, 'gfx, 'pass> { text.translation += Point::::from_px(self.translation(), self.scale()); self.renderer.draw_measured_text(text, origin); } + + /// Returns this renderer as a + /// [`DrawingArea`](plotters::drawing::DrawingArea) compatible with the + /// [plotters](https://github.com/plotters-rs/plotters) crate. + #[cfg(feature = "plotters")] + pub fn as_plot_area( + &mut self, + ) -> plotters::drawing::DrawingArea< + kludgine::drawing::PlotterBackend<'_, 'gfx, 'pass>, + plotters::coord::Shift, + > { + self.renderer.as_plot_area() + } } impl<'gfx, 'pass> Deref for Graphics<'_, 'gfx, 'pass> { diff --git a/src/window.rs b/src/window.rs index 527ee46..a17835c 100644 --- a/src/window.rs +++ b/src/window.rs @@ -33,7 +33,7 @@ use kludgine::app::winit::keyboard::{ use kludgine::app::winit::window::{self, CursorIcon}; use kludgine::app::{winit, WindowBehavior as _}; use kludgine::cosmic_text::{fontdb, Family, FamilyOwned}; -use kludgine::render::Drawing; +use kludgine::drawing::Drawing; use kludgine::shapes::Shape; use kludgine::wgpu::{self, CompositeAlphaMode, COPY_BYTES_PER_ROW_ALIGNMENT}; use kludgine::{Color, DrawableExt, Kludgine, KludgineId, Origin, Texture};