Skip to content
Snippets Groups Projects
Commit b2c73725 authored by Martin Morin's avatar Martin Morin
Browse files

Add basic layout and app switching

parent 88a6542b
Branches
No related tags found
No related merge requests found
#![warn(clippy::all, rust_2018_idioms)] #![warn(clippy::all, rust_2018_idioms)]
#[allow(unused_imports)] #[allow(unused_imports)]
use basic_print::basic_print; use basic_print::basic_print; // basic print for print-debugging
pub struct TemplateApp {
label: String,
value: f32,
}
impl Default for TemplateApp { pub struct ControlApp {
fn default() -> Self { cur_app_idx: Option<usize>,
Self { apps: Vec<(String,SubApp)>,
// Example stuff:
label: "Hello World!".to_owned(),
value: 2.7,
}
} }
#[derive(PartialEq)]
enum SubApp {
PolePos,
FreqResp,
} }
impl TemplateApp { impl ControlApp {
/// Called once before the first frame.
pub fn new(_cc: &eframe::CreationContext<'_>) -> Self { pub fn new(_cc: &eframe::CreationContext<'_>) -> Self {
// This is also where you can customized the look at feel of egui using // This is also where you can customized the look at feel of egui using
// `cc.egui_ctx.set_visuals` and `cc.egui_ctx.set_fonts`. // `cc.egui_ctx.set_visuals` and `cc.egui_ctx.set_fonts`.
Default::default() let pp = ("Pole Positioning".to_string(), SubApp::PolePos);
let fr = ("Frequency Response".to_string(), SubApp::FreqResp);
ControlApp{cur_app_idx: None, apps: vec![pp,fr] }
}
fn top_bar(&mut self, ui: &mut egui::Ui) -> bool {
#[allow(unused_mut)]
let mut quit = false;
ui.horizontal_wrapped(|ui| {
ui.heading("Control Apps");
ui.separator();
for (idx, (label, _app)) in self.apps.iter().enumerate() {
let checked = match self.cur_app_idx {
Some(cur) => cur == idx,
None => false,
};
if ui.selectable_label(checked, label).clicked() {
if checked {
self.cur_app_idx = None;
} else {
self.cur_app_idx = Some(idx);
}
} }
} }
impl eframe::App for TemplateApp {
/// Called each time the UI needs repainting, which may be many times per second. ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
/// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`. #[cfg(not(target_arch = "wasm32"))] // no quit on web pages!
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { {
let Self { label, value } = self;
// Examples of how to create different panels and windows.
// Pick whichever suits you.
// Tip: a good default choice is to just keep the `CentralPanel`.
// For inspiration and more examples, go to https://emilk.github.io/egui
#[cfg(not(target_arch = "wasm32"))] // no File->Quit on web pages!
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
// The top panel is often a good place for a menu bar:
egui::menu::bar(ui, |ui| {
ui.menu_button("File", |ui| {
if ui.button("Quit").clicked() { if ui.button("Quit").clicked() {
_frame.close(); quit = true;
} }
}); ui.separator();
}); }
egui::warn_if_debug_build(ui);
}); });
egui::SidePanel::left("side_panel").show(ctx, |ui| {
ui.heading("Side Panel");
ui.horizontal(|ui| {
ui.label("Write something: ");
ui.text_edit_singleline(label);
}); });
ui.add(egui::Slider::new(value, 0.0..=10.0).text("value")); return quit
if ui.button("Increment:").clicked() {
*value += 1.0;
} }
ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| { }
ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 0.0; impl eframe::App for ControlApp {
ui.label("powered by ");
ui.hyperlink_to("egui", "https://github.com/emilk/egui"); fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
ui.label(" and "); egui::TopBottomPanel::top("app_selection_panel").show(ctx, |ui| {
ui.hyperlink_to( if self.top_bar(ui) {
"eframe", #[cfg(not(target_arch = "wasm32"))] // no quit on web pages!
"https://github.com/emilk/egui/tree/master/crates/eframe", _frame.close();
); }
ui.label(".");
});
});
}); });
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
// The central panel the region left after adding TopPanel's and SidePanel's ui.centered_and_justified( |ui| {
match self.cur_app_idx {
ui.heading("eframe template"); Some(idx) => ui.label(self.apps[idx].0.to_string()),
ui.hyperlink("https://github.com/emilk/eframe_template"); None => ui.label("Select an application in the bar above."),
ui.add(egui::github_link_file!( };
"https://github.com/emilk/eframe_template/blob/master/",
"Source code."
));
egui::warn_if_debug_build(ui);
}); });
if true {
egui::Window::new("Window").show(ctx, |ui| {
ui.label("Windows can be moved by dragging them.");
ui.label("They are automatically sized based on contents.");
ui.label("You can turn on resizing and scrolling if you like.");
ui.label("You would normally chose either panels OR windows.");
}); });
} }
} }
}
// impl eframe::App for TemplateApp {
// fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
// let Self { label, value } = self;
// egui::SidePanel::left("side_panel").show(ctx, |ui| {
// ui.heading("Side Panel");
// ui.horizontal(|ui| {
// ui.label("Write something: ");
// ui.text_edit_singleline(label);
// });
// ui.add(egui::Slider::new(value, 0.0..=10.0).text("value"));
// if ui.button("Increment:").clicked() {
// *value += 1.0;
// }
// ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| {
// ui.horizontal(|ui| {
// ui.spacing_mut().item_spacing.x = 0.0;
// ui.label("powered by ");
// ui.hyperlink_to("egui", "https://github.com/emilk/egui");
// ui.label(" and ");
// ui.hyperlink_to(
// "eframe",
// "https://github.com/emilk/egui/tree/master/crates/eframe",
// );
// ui.label(".");
// });
// });
// });
// }
// }
#![warn(clippy::all, rust_2018_idioms)] #![warn(clippy::all, rust_2018_idioms)]
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
use basic_print::basic_print; use basic_print::basic_print; // eframe already has this kind of logging so I should probably figure out if that it expose some item for that.
// Application startin points for the two targets // Application startin points for the two targets
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
...@@ -15,7 +15,8 @@ fn main() { ...@@ -15,7 +15,8 @@ fn main() {
eframe::run_native( eframe::run_native(
"eframe template", "eframe template",
native_options, native_options,
Box::new(|cc| Box::new(control_web_apps::TemplateApp::new(cc))), // Box::new(|cc| Box::new(control_web_apps::TemplateApp::new(cc))),
Box::new(|cc| Box::new(control_web_apps::ControlApp::new(cc))),
); );
} }
...@@ -33,7 +34,8 @@ fn main() { ...@@ -33,7 +34,8 @@ fn main() {
eframe::start_web( eframe::start_web(
"the_canvas_id", // hardcode it "the_canvas_id", // hardcode it
web_options, web_options,
Box::new(|cc| Box::new(control_web_apps::TemplateApp::new(cc))), // Box::new(|cc| Box::new(control_web_apps::TemplateApp::new(cc))),
Box::new(|cc| Box::new(control_web_apps::ControlApp::new(cc))),
) )
.expect("failed to start eframe"); .expect("failed to start eframe");
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment