August 15, 2024 in Development, Showcase3 minutes
This is the first article in a series documenting my progress on the Graph Notes project.
My primary goal for today is to get some scaffolding in place. At the end of this, I’ll have a repository, some commits for you to explore, and enough of a project that you could pull down and run if so inclined.
First, the repo, which can be found on GitHub: https://github.com/bellwether-softworks/graph_note.
The initial commit contains the results of running cargo new
, followed by a commit to supply the license (MIT).
I’ll mention up-front that this project’s structure may evolve over time as need dictates. For now, a single application suits my needs, but I can also envision a future where things are decoupled (e.g. a project for business logic, one for an API server, another for the front-facing application). Today, I’m keeping it simple.
I’ve talked before about creating a new project with egui. In that article, I relied on a template project to wire a lot of stuff up; today, I’m instead going to do it by hand, in part to give that perspective to anyone looking for what it takes to inject egui into an existing project. That said, I’ll be referring to the template project’s Cargo.toml file to help inform my dependency selections:
$ cargo add serde@1 --features derive
$ cargo add egui
$ cargo add egui_extras
$ cargo add eframe --no-default-features --features accesskit,default_fonts,glow
For today, I’m developing a local executable, but I’m likely going to revisit the Cargo.toml to add support for WASM targets.
Also, while we’re in the template project, we’ll want to look at how they structure the app:
I’ll start first by adapting the fn main()
implementation from the template
to our own needs, starting simple; the full file contents for the moment are as shown below:
mod app;
#[cfg(not(target_arch = "wasm32"))]
fn main() -> eframe::Result {
let native_options = eframe::NativeOptions::default();
eframe::run_native(
"Graph Notes",
native_options,
Box::new(|cc| Ok(Box::new(app::App::new(cc)))),
)
}
You can see I’m referencing a yet-to-be-created app::App
struct; let’s head over to src/app.rs and flesh out the
minimum requirements for our nascent egui application:
use eframe::Frame;
use egui::Context;
pub struct App;
impl Default for App {
fn default() -> Self {
Self
}
}
impl App {
pub fn new(_cc: &eframe::CreationContext<'_>) -> Self {
// Access to the CreationContext during instantiation allows us to take
// ownership of some aspects of our app, such as wiring up fonts.
Default::default()
}
}
impl eframe::App for App {
fn update(&mut self, ctx: &Context, frame: &mut Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.label("Greetings from the skeleton app.");
});
}
}
The eframe::App
trait offers us more hooks to take advantage of, but shown here is just enough code to be able
to render out the following:
Nothing fancy thus far, but this gives us enough of a starting point that we can start fleshing out some ideas in our next go.