From ed012e40b1d5694ded4ff54d58cc0d56e45eafb6 Mon Sep 17 00:00:00 2001 From: Wynd Date: Sat, 31 May 2025 00:46:48 +0300 Subject: [PATCH] Basic but working sort visualizer --- .gitignore | 1 + Cargo.lock | 255 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 9 ++ rust-toolchain.toml | 2 + rustfmt.toml | 8 ++ src/main.rs | 113 ++++++++++++++++++++ 6 files changed, 388 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 rust-toolchain.toml create mode 100644 rustfmt.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..d891763 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,255 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "cc" +version = "1.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + +[[package]] +name = "cmk" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd5de2a10e31b3ec3e8d75e7ccf8281ab3ee55de68f7ab6ffa9e21be8d82f22" + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "fltk" +version = "1.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecfe1d97c0be7585b46d52c1e563226a6495a993be2c72dcdd03fe79d29b1f2a" +dependencies = [ + "bitflags", + "crossbeam-channel", + "fltk-sys", + "once_cell", + "paste", + "ttf-parser", +] + +[[package]] +name = "fltk-sys" +version = "1.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de39f27a66d3ceefca611ee2db890369c6846fde4de7b5fd7cdedd9ce0c432f8" +dependencies = [ + "cmake", + "cmk", +] + +[[package]] +name = "fltk-theme" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eac14d47a555db231b4ce9729118a7c57c8a21714af008b8e9ae627998edb7a" +dependencies = [ + "fltk", +] + +[[package]] +name = "fltk-visualize" +version = "0.1.0" +dependencies = [ + "fltk", + "fltk-theme", + "rand", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.172" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "syn" +version = "2.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] +name = "zerocopy" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..4ac99c4 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "fltk-visualize" +version = "0.1.0" +edition = "2021" + +[dependencies] +rand = { version = "0.9" } +fltk = { version = "1.5" } +fltk-theme = { version = "0.7" } diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..f85d150 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly-2025-04-07" diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..3116f8a --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,8 @@ +unstable_features = true +reorder_imports = true +hard_tabs = true +control_brace_style = "ClosingNextLine" +imports_granularity = "Crate" +group_imports = "StdExternalCrate" +edition = "2021" +newline_style = "Unix" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..4810d25 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,113 @@ +use std::{ + sync::mpsc::{self, Sender}, + thread, +}; + +use fltk::{ + app, + enums::{Color, FrameType}, + misc::Chart, + prelude::{GroupExt, WidgetExt, WindowExt}, + window::Window, +}; +use fltk_theme::{color_themes, ColorTheme}; +use rand::Rng; + +const SIZE: u32 = 50; +const MAX_VALUE: f64 = 100.0; + +type Sorter = fn(SortVisualizer); + +#[derive(Debug, Clone)] +struct SortVisualizer { + chart: Chart, + arr: Vec, + sorter: Sorter, + tx: Sender, +} + +impl SortVisualizer { + fn new(tx: Sender, arr: Vec, sorter: Sorter) -> Self { + let mut chart = Chart::default(); + chart.set_size(500, 250); + chart.set_frame(FrameType::FlatBox); + chart.set_bounds(0.0, MAX_VALUE); + Self { + tx, + chart, + arr, + sorter, + } + } + + fn sort(self) { + (self.sorter)(self); + } + + fn redraw(&mut self) { + self.chart.clear(); + for i in &self.arr { + self.chart.add(*i, "", Color::Cyan); + } + } +} + +fn quick_sort(arr: &mut Vec, vis: &mut SortVisualizer) {} + +fn bubble_sort(mut vis: SortVisualizer) { + let n = vis.arr.len(); + + for i in 0..n { + for j in 0..n - i - 1 { + if vis.arr[j] > vis.arr[j + 1] { + vis.arr.swap(j, j + 1); + + vis.tx.send(vis.clone()).unwrap(); + } + } + } +} + +fn main() { + let mut arr: Vec = (1..SIZE) + .map(|_| rand::rng().random_range(1.0..MAX_VALUE)) + .collect(); + + let (tx, rx) = mpsc::channel(); + + let sorts = [bubble_sort]; + // let mut visualizers = vec![]; + + let app = app::App::default().with_scheme(app::Scheme::Gtk); + let theme = ColorTheme::new(&color_themes::fleet::DARK1); + theme.apply(); + + let mut window = Window::default() + .with_size(640, 480) + .with_label("FLTK Visualizer"); + window.size_range(640, 480, 0, 0); + + let mut vis = SortVisualizer::new(tx, arr, bubble_sort); + // visualizers.push(vis); + + window.end(); + window.show(); + + let handle = thread::spawn(move || { + vis.sort(); + }); + + app::add_idle3(move |_| { + let vis = rx.recv(); + if let Ok(mut vis) = vis { + vis.redraw(); + } + + window.redraw(); + app::sleep(0.016); + }); + + app.run().unwrap(); + + handle.join().unwrap(); +}