1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-27 23:13:13 -04:00

egui_web: Add simple fetch API and demostrate it in example_web

This commit is contained in:
Emil Ernerfeldt
2020-11-18 00:43:58 +01:00
parent 0cb3bb791b
commit fad0029119
8 changed files with 1046 additions and 26 deletions

View File

@@ -1,15 +1,18 @@
/// We derive Deserialize/Serialize so we can persist app state on shutdown.
#[derive(serde::Deserialize, serde::Serialize)]
use egui_web::fetch::Response;
use std::sync::mpsc::Receiver;
pub struct ExampleApp {
name: String,
age: u32,
url: String,
receivers: Vec<Receiver<Result<Response, String>>>,
fetch_result: Option<Result<Response, String>>,
}
impl Default for ExampleApp {
fn default() -> Self {
Self {
name: "Arthur".to_owned(),
age: 42,
url: "https://raw.githubusercontent.com/emilk/egui/master/README.md".to_owned(),
receivers: Default::default(),
fetch_result: Default::default(),
}
}
}
@@ -20,30 +23,82 @@ impl egui::app::App for ExampleApp {
fn ui(
&mut self,
ctx: &std::sync::Arc<egui::Context>,
integration_context: &mut egui::app::IntegrationContext,
_integration_context: &mut egui::app::IntegrationContext,
) {
let ExampleApp { name, age } = self;
// Example used in `README.md`.
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("My Egui Application");
ui.heading("HTTP Get inside of Egui");
ui.add(egui::github_link_file!(
"https://github.com/emilk/egui/blob/master/",
"(source code)"
));
ui.horizontal(|ui| {
ui.label("Your name: ");
ui.text_edit_singleline(name);
});
{
let mut trigger_fetch = false;
ui.add(egui::Slider::u32(age, 0..=120).text("age"));
if ui.button("Click each year").clicked {
*age += 1;
ui.horizontal(|ui| {
ui.label("URL:");
trigger_fetch |= ui.text_edit_singleline(&mut self.url).lost_kb_focus;
if ui.button("Egui README.md").clicked {
self.url = "https://raw.githubusercontent.com/emilk/egui/master/README.md"
.to_owned();
}
if ui.button("Source code for this file").clicked {
self.url =
format!("https://raw.githubusercontent.com/emilk/egui/{}", file!());
}
});
trigger_fetch |= ui.button("GET").clicked;
if trigger_fetch {
let (sender, receiver) = std::sync::mpsc::channel();
self.receivers.push(receiver);
let url = self.url.clone();
let future = async move {
let result = egui_web::fetch::get_text(&url).await;
sender.send(result).ok();
// TODO: trigger egui repaint somehow
};
egui_web::spawn_future(future);
}
}
ui.label(format!("Hello '{}', age {}", name, age));
ui.advance_cursor(16.0);
if ui.button("Quit").clicked {
integration_context.output.quit = true;
// Show finished download (if any):
if let Some(result) = &self.fetch_result {
ui.separator();
match result {
Ok(response) => {
ui_response(ui, response);
}
Err(error) => {
// This should only happen if the fetch API isn't available or something similar.
ui.add(egui::Label::new(error).text_color(egui::color::RED));
}
}
}
});
for i in (0..self.receivers.len()).rev() {
if let Ok(result) = self.receivers[i].try_recv() {
self.fetch_result = Some(result);
let _ = self.receivers.swap_remove(i);
}
}
}
}
fn ui_response(ui: &mut egui::Ui, response: &Response) {
ui.monospace(format!("url: {}", response.url));
ui.monospace(format!(
"status: {} ({})",
response.status, response.status_text
));
ui.monospace("Body:");
ui.separator();
egui::ScrollArea::auto_sized().show(ui, |ui| {
ui.monospace(&response.body);
});
}