servoshell: Port alert/confirm dialog code to use egui intead of tinyfiledialogs (#35399)

Signed-off-by: L Ashwin B <lashwinib@gmail.com>
This commit is contained in:
chickenleaf 2025-02-12 17:17:36 +05:30 committed by GitHub
parent 87069e9f47
commit 82df628a11
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 140 additions and 91 deletions

View file

@ -5,21 +5,26 @@
use std::path::{Path, PathBuf};
use std::sync::Arc;
use egui::Modal;
use egui_file_dialog::{DialogState, FileDialog as EguiFileDialog};
use log::warn;
use servo::ipc_channel::ipc::IpcSender;
use servo::FilterPattern;
use servo::{FilterPattern, PromptResult};
#[derive(Debug)]
pub struct FileDialog {
dialog: EguiFileDialog,
multiple: bool,
response_sender: IpcSender<Option<Vec<PathBuf>>>,
}
#[derive(Debug)]
pub enum Dialog {
File(FileDialog),
File {
dialog: EguiFileDialog,
multiple: bool,
response_sender: IpcSender<Option<Vec<PathBuf>>>,
},
Alert {
message: String,
sender: IpcSender<()>,
},
OkCancel {
message: String,
sender: IpcSender<PromptResult>,
},
}
impl Dialog {
@ -45,44 +50,53 @@ impl Dialog {
.default_file_filter("All Supported Types");
}
let dialog = FileDialog {
Dialog::File {
dialog,
multiple,
response_sender,
};
}
}
Dialog::File(dialog)
pub fn new_alert_dialog(message: String, sender: IpcSender<()>) -> Self {
Dialog::Alert { message, sender }
}
pub fn new_okcancel_dialog(message: String, sender: IpcSender<PromptResult>) -> Self {
Dialog::OkCancel { message, sender }
}
pub fn update(&mut self, ctx: &egui::Context) -> bool {
match self {
Dialog::File(dialog) => {
if dialog.dialog.state() == DialogState::Closed {
if dialog.multiple {
dialog.dialog.pick_multiple();
Dialog::File {
dialog,
multiple,
response_sender,
} => {
if dialog.state() == DialogState::Closed {
if *multiple {
dialog.pick_multiple();
} else {
dialog.dialog.pick_file();
dialog.pick_file();
}
}
let state = dialog.dialog.update(ctx).state();
let state = dialog.update(ctx).state();
match state {
DialogState::Open => true,
DialogState::Picked(path) => {
if let Err(e) = dialog.response_sender.send(Some(vec![path])) {
if let Err(e) = response_sender.send(Some(vec![path])) {
warn!("Failed to send file selection response: {}", e);
}
false
},
DialogState::PickedMultiple(paths) => {
if let Err(e) = dialog.response_sender.send(Some(paths)) {
if let Err(e) = response_sender.send(Some(paths)) {
warn!("Failed to send file selection response: {}", e);
}
false
},
DialogState::Cancelled => {
if let Err(e) = dialog.response_sender.send(None) {
if let Err(e) = response_sender.send(None) {
warn!("Failed to send cancellation response: {}", e);
}
false
@ -90,10 +104,59 @@ impl Dialog {
DialogState::Closed => false,
}
},
Dialog::Alert { message, sender } => {
let mut is_open = true;
let modal = Modal::new("alert".into());
modal.show(ctx, |ui| {
make_dialog_label(message, ui);
egui::Sides::new().show(
ui,
|_ui| {},
|ui| {
if ui.button("Close").clicked() {
is_open = false;
if let Err(e) = sender.send(()) {
warn!("Failed to send alert dialog response: {}", e);
}
}
},
);
});
is_open
},
Dialog::OkCancel { message, sender } => {
let mut is_open = true;
let modal = Modal::new("OkCancel".into());
modal.show(ctx, |ui| {
make_dialog_label(message, ui);
egui::Sides::new().show(
ui,
|_ui| {},
|ui| {
if ui.button("Ok").clicked() {
is_open = false;
if let Err(e) = sender.send(PromptResult::Primary) {
warn!("Failed to send alert dialog response: {}", e);
}
}
if ui.button("Cancel").clicked() {
is_open = false;
if let Err(e) = sender.send(PromptResult::Secondary) {
warn!("Failed to send alert dialog response: {}", e);
}
}
},
);
});
is_open
},
}
}
pub(crate) fn is_file_dialog(&self) -> bool {
matches!(self, Dialog::File(..))
}
}
fn make_dialog_label(message: &str, ui: &mut egui::Ui) {
let mut frame = egui::Frame::default().inner_margin(10.0).begin(ui);
frame.content_ui.set_min_width(150.0);
frame.content_ui.label(message);
frame.end(ui);
}