From f2c2dca4be31ee8df5081c91d6ffedf75f890ff1 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Mon, 19 Feb 2024 03:12:46 +0000 Subject: [PATCH] cargo: introduce topola-gui binary crate --- Cargo.toml | 49 +++++++++++++-- src/bin/topola-gui/app.rs | 60 +++++++++++++++++++ src/bin/topola-gui/main.rs | 42 +++++++++++++ .../app.rs => bin/topola-sdl2-demo/main.rs} | 30 +++++----- src/lib.rs | 13 ++++ src/main.rs | 25 -------- 6 files changed, 173 insertions(+), 46 deletions(-) create mode 100644 src/bin/topola-gui/app.rs create mode 100644 src/bin/topola-gui/main.rs rename src/{app/sdl2_demo/app.rs => bin/topola-sdl2-demo/main.rs} (96%) create mode 100644 src/lib.rs delete mode 100644 src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 6208c0f..f1d751c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,12 +2,18 @@ name = "topola" version = "0.1.0" edition = "2021" +default-run = "topola-gui" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "topola" -[features] -default = ["sdl2_demo"] -sdl2_demo = ["dep:sdl2"] +[[bin]] +name = "topola-gui" +required-features = ["egui", "eframe"] + +[[bin]] +name = "topola-sdl2-demo" +required-features = ["sdl2"] [dependencies] gl = "0.14.0" @@ -40,11 +46,42 @@ version = "0.8.2" [dependencies.contracts] version = "0.6.3" -[dependencies.sdl2] -version = "0.35.2" +[dependencies.log] optional = true +version = "0.4" + +[dependencies.serde] +version = "1" +features = ["derive"] + +[dependencies.egui] +optional = true +version = "0.26.0" + +[dependencies.eframe] +optional = true +version = "0.26.0" +default-features = false +features = ["accesskit", "default_fonts", "glow", "persistence"] + +[dependencies.sdl2] +optional = true +version = "0.35.2" default-features = false features = ["bundled"] +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +env_logger = "0.10" + +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-bindgen-futures = "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] contracts = { path = "vendored/contracts" } diff --git a/src/bin/topola-gui/app.rs b/src/bin/topola-gui/app.rs new file mode 100644 index 0000000..6dcecd9 --- /dev/null +++ b/src/bin/topola-gui/app.rs @@ -0,0 +1,60 @@ +/// Deserialize/Serialize is needed to persist app state between restarts. +#[derive(serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct TemplateApp { + // Example stuff: + label: String, + + #[serde(skip)] // Don't serialize this field. + value: f32, +} + +impl Default for TemplateApp { + fn default() -> Self { + Self { + // Example stuff: + label: "Hello World!".to_owned(), + value: 2.7, + } + } +} + +impl TemplateApp { + /// Called once on start. + pub fn new(cc: &eframe::CreationContext<'_>) -> Self { + // Load previous app state if one exists. + if let Some(storage) = cc.storage { + return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default(); + } + + Default::default() + } +} + +impl eframe::App for TemplateApp { + /// Called to save state before shutdown. + fn save(&mut self, storage: &mut dyn eframe::Storage) { + eframe::set_value(storage, eframe::APP_KEY, self); + } + + /// Called each time the UI has to be repainted. + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { + egui::menu::bar(ui, |ui| { + let is_web = cfg!(target_arch = "wasm32"); + if !is_web { + ui.menu_button("File", |ui| { + if ui.button("Quit").clicked() { + ctx.send_viewport_cmd(egui::ViewportCommand::Close); + } + }); + ui.add_space(16.0); + } + + egui::widgets::global_dark_light_mode_buttons(ui); + }); + }); + + egui::CentralPanel::default().show(ctx, |ui| {}); + } +} diff --git a/src/bin/topola-gui/main.rs b/src/bin/topola-gui/main.rs new file mode 100644 index 0000000..a5119af --- /dev/null +++ b/src/bin/topola-gui/main.rs @@ -0,0 +1,42 @@ +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release + +mod app; +use app::TemplateApp; + +// Build to native. +#[cfg(not(target_arch = "wasm32"))] +fn main() -> eframe::Result<()> { + env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). + + let native_options = eframe::NativeOptions { + viewport: egui::ViewportBuilder::default() + .with_inner_size([400.0, 300.0]) + .with_min_inner_size([300.0, 220.0]), + ..Default::default() + }; + eframe::run_native( + "eframe template", + native_options, + Box::new(|cc| Box::new(TemplateApp::new(cc))), + ) +} + +// Build to Web. +#[cfg(target_arch = "wasm32")] +fn main() { + // Redirect `log` message to `console.log`: + eframe::WebLogger::init(log::LevelFilter::Debug).ok(); + + let web_options = eframe::WebOptions::default(); + + wasm_bindgen_futures::spawn_local(async { + eframe::WebRunner::new() + .start( + "the_canvas_id", + web_options, + Box::new(|cc| Box::new(TemplateApp::new(cc))), + ) + .await + .expect("failed to start eframe"); + }); +} diff --git a/src/app/sdl2_demo/app.rs b/src/bin/topola-sdl2-demo/main.rs similarity index 96% rename from src/app/sdl2_demo/app.rs rename to src/bin/topola-sdl2-demo/main.rs index 600ebb6..b262369 100644 --- a/src/app/sdl2_demo/app.rs +++ b/src/bin/topola-sdl2-demo/main.rs @@ -7,19 +7,19 @@ macro_rules! dbg_dot { }; } -use crate::draw::DrawException; -use crate::layout::connectivity::BandIndex; -use crate::layout::dot::FixedDotWeight; -use crate::layout::geometry::shape::{Shape, ShapeTrait}; -use crate::layout::graph::{GeometryIndex, MakePrimitive}; -use crate::layout::primitive::MakeShape; -use crate::layout::rules::{Conditions, RulesTrait}; -use crate::layout::seg::FixedSegWeight; -use crate::layout::{Infringement, Layout, LayoutException}; -use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex}; -use crate::router::RouterObserverTrait; use geo::point; use petgraph::visit::{EdgeRef, IntoEdgeReferences}; +use topola::draw::DrawException; +use topola::layout::connectivity::BandIndex; +use topola::layout::dot::FixedDotWeight; +use topola::layout::geometry::shape::{Shape, ShapeTrait}; +use topola::layout::graph::{GeometryIndex, MakePrimitive}; +use topola::layout::primitive::MakeShape; +use topola::layout::rules::{Conditions, RulesTrait}; +use topola::layout::seg::FixedSegWeight; +use topola::layout::{Infringement, Layout, LayoutException}; +use topola::mesh::{Mesh, MeshEdgeReference, VertexIndex}; +use topola::router::RouterObserverTrait; use sdl2::event::Event; use sdl2::keyboard::Keycode; @@ -38,12 +38,12 @@ use pathfinder_renderer::gpu::renderer::Renderer; use pathfinder_renderer::options::BuildOptions; use pathfinder_resources::embedded::EmbeddedResourceLoader; -use crate::tracer::{Trace, Tracer}; use std::collections::HashMap; use std::time::Duration; +use topola::tracer::{Trace, Tracer}; -use crate::math::Circle; -use crate::router::Router; +use topola::math::Circle; +use topola::router::Router; struct SimpleRules { net_clearances: HashMap<(i64, i64), f64>, @@ -184,7 +184,7 @@ impl<'a, R: RulesTrait> RouterObserverTrait for DebugRouterObserver<'a> { fn on_estimate(&mut self, _tracer: &Tracer, _vertex: VertexIndex) {} } -pub fn run() -> Result<(), anyhow::Error> { +fn main() -> Result<(), anyhow::Error> { let sdl_context = sdl2::init().unwrap(); let video_subsystem = sdl_context.video().unwrap(); diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..9ef767c --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,13 @@ +#![feature(try_blocks)] + +pub mod astar; +pub mod draw; +pub mod graph; +#[macro_use] +pub mod layout; +pub mod math; +pub mod mesh; +pub mod router; +pub mod tracer; +pub mod triangulation; +pub mod wraparoundable; diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 2374171..0000000 --- a/src/main.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![feature(try_blocks)] - -mod astar; -mod draw; -mod graph; -#[macro_use] -mod layout; -mod math; -mod mesh; -mod router; -mod tracer; -mod triangulation; -mod wraparoundable; - -#[cfg_attr(feature = "sdl2_demo", path = "app/sdl2_demo/app.rs")] -mod app; - -#[cfg(feature = "sdl2_demo")] -pub fn run() -> Result<(), anyhow::Error> { - app::run() -} - -fn main() -> Result<(), anyhow::Error> { - run() -}