use crate::prelude::*;
pub struct DroppedFile {
pub path: Option<std::path::PathBuf>,
pub name: String,
pub bytes: Option<std::sync::Arc<[u8]>>,
}
pub fn get_dropped_files(ui_context: &egui::Context) -> Vec<DroppedFile> {
ui_context.input(|input| {
input
.raw
.dropped_files
.iter()
.map(|file| DroppedFile {
path: file.path.clone(),
name: file.name.clone(),
bytes: file.bytes.clone(),
})
.collect()
})
}
pub fn is_file_hovering(ui_context: &egui::Context) -> bool {
ui_context.input(|input| !input.raw.hovered_files.is_empty())
}
pub fn render_drop_overlay(ui_context: &egui::Context, message: &str) {
if !is_file_hovering(ui_context) {
return;
}
let screen_rect = ui_context.content_rect();
egui::Area::new(egui::Id::new("drop_overlay"))
.fixed_pos(screen_rect.min)
.order(egui::Order::Foreground)
.show(ui_context, |ui| {
let painter = ui.painter();
painter.rect_filled(screen_rect, 0.0, egui::Color32::from_black_alpha(160));
painter.text(
screen_rect.center(),
egui::Align2::CENTER_CENTER,
message,
egui::FontId::proportional(24.0),
egui::Color32::WHITE,
);
});
}
pub struct FileCategory {
pub extensions: &'static [&'static str],
pub suffixes: &'static [&'static str],
pub name: &'static str,
}
pub fn categorize_file<'a>(
path: &std::path::Path,
categories: &'a [FileCategory],
) -> Option<&'a str> {
let extension = path
.extension()
.and_then(|extension| extension.to_str())
.map(|extension| extension.to_lowercase());
let filename_lower = path.to_string_lossy().to_lowercase();
for category in categories {
for suffix in category.suffixes {
if filename_lower.ends_with(suffix) {
return Some(category.name);
}
}
if let Some(ref extension) = extension {
for category_extension in category.extensions {
if extension == *category_extension {
return Some(category.name);
}
}
}
}
None
}
pub fn render_drop_overlay_with_category(
ui_context: &egui::Context,
category: Option<&str>,
messages: &[(&str, &str)],
default_message: &str,
) {
let message = category
.and_then(|category| {
messages
.iter()
.find(|(name, _)| *name == category)
.map(|(_, message)| *message)
})
.unwrap_or(default_message);
egui::Area::new(egui::Id::new("drop_indicator"))
.anchor(egui::Align2::CENTER_CENTER, [0.0, 0.0])
.show(ui_context, |ui| {
ui.with_layout(egui::Layout::top_down(egui::Align::Center), |ui| {
let frame = egui::Frame::default()
.fill(egui::Color32::from_rgba_premultiplied(30, 30, 30, 200))
.corner_radius(10.0)
.stroke(egui::Stroke::new(
2.0,
egui::Color32::from_rgb(100, 150, 250),
))
.inner_margin(30.0);
frame.show(ui, |ui| {
ui.heading(message);
});
});
});
}