added an all layer option to exports

This commit is contained in:
grimsace
2026-04-28 13:14:13 -05:00
parent 6c6ea3778e
commit 51bb936263
3 changed files with 78 additions and 39 deletions
+62 -23
View File
@@ -136,8 +136,13 @@ fn collect_scene_data(layout: &DungeonLayout, settings: &UiSettings) -> SceneDat
// Open a dialog to select an export destination.
pub fn select_export_target(settings: &UiSettings) -> Result<ExportTarget, String> {
if settings.export_format == ExportFormat::Folder {
let mut dialog = FileDialog::new().set_title("Export composite masks folder");
if settings.export_format == ExportFormat::Folder || settings.export_level_index == 999 {
let title = if settings.export_level_index == 999 {
"Select export folder for all levels"
} else {
"Export composite masks folder"
};
let mut dialog = FileDialog::new().set_title(title);
if let Some(ref last_path) = settings.last_export_path {
dialog = dialog.set_directory(last_path);
}
@@ -173,40 +178,74 @@ pub fn select_export_target(settings: &UiSettings) -> Result<ExportTarget, Strin
// Export the current layout to the chosen file or folder target.
pub fn export_to_target(
layout: &DungeonLayout,
layouts: &[DungeonLayout],
settings: &UiSettings,
target: ExportTarget,
) -> Result<PathBuf, String> {
let export_indices: Vec<usize> = if settings.export_level_index == 999 {
(0..layouts.len()).collect()
} else {
let idx = settings
.export_level_index
.min(layouts.len().saturating_sub(1));
vec![idx]
};
match target {
ExportTarget::Folder(folder) => {
export_composite_masks(layout, settings, &folder)?;
for &idx in &export_indices {
let layout = &layouts[idx];
if settings.export_format == ExportFormat::Folder {
let subfolder = if settings.export_level_index == 999 {
folder.join(format!("level {}", idx + 1))
} else {
folder.clone()
};
export_composite_masks(layout, settings, &subfolder)?;
} else {
let ext = settings.export_format.extension();
let filename = format!("level{}.{ext}", idx + 1);
let path = folder.join(filename);
save_layout_to_file(layout, settings, &path)?;
}
}
Ok(folder)
}
ExportTarget::File(path) => {
match settings.export_format {
ExportFormat::Svg => {
let svg = build_svg(layout, settings);
std::fs::write(&path, svg).map_err(|e| format!("Failed writing SVG: {e}"))?;
}
ExportFormat::Png | ExportFormat::Jpeg | ExportFormat::Webp => {
let pixmap = render_pixmap(layout, settings)?;
let img = raster_image_from_pixmap(&pixmap, settings)?;
let format = match settings.export_format {
ExportFormat::Png => ImageFormat::Png,
ExportFormat::Jpeg => ImageFormat::Jpeg,
ExportFormat::Webp => ImageFormat::WebP,
ExportFormat::Svg | ExportFormat::Folder => unreachable!(),
};
img.save_with_format(&path, format)
.map_err(|e| format!("Failed writing image: {e}"))?;
}
ExportFormat::Folder => unreachable!(),
}
let idx = export_indices[0];
save_layout_to_file(&layouts[idx], settings, &path)?;
Ok(path)
}
}
}
fn save_layout_to_file(
layout: &DungeonLayout,
settings: &UiSettings,
path: &std::path::Path,
) -> Result<(), String> {
match settings.export_format {
ExportFormat::Svg => {
let svg = build_svg(layout, settings);
std::fs::write(path, svg).map_err(|e| format!("Failed writing SVG: {e}"))?;
}
ExportFormat::Png | ExportFormat::Jpeg | ExportFormat::Webp => {
let pixmap = render_pixmap(layout, settings)?;
let img = raster_image_from_pixmap(&pixmap, settings)?;
let format = match settings.export_format {
ExportFormat::Png => ImageFormat::Png,
ExportFormat::Jpeg => ImageFormat::Jpeg,
ExportFormat::Webp => ImageFormat::WebP,
ExportFormat::Svg | ExportFormat::Folder => unreachable!(),
};
img.save_with_format(path, format)
.map_err(|e| format!("Failed writing image: {e}"))?;
}
ExportFormat::Folder => unreachable!(),
}
Ok(())
}
// Render the dungeon layout to a pixmap.
fn render_pixmap(layout: &DungeonLayout, settings: &UiSettings) -> Result<Pixmap, String> {
let g = ExportGeometry::new(settings.cols, settings.rows);
+8 -14
View File
@@ -223,20 +223,14 @@ impl eframe::App for DungeonApp {
}
}
let export_idx = self
.settings
.export_level_index
.min(self.levels.len().saturating_sub(1));
if export_idx < self.levels.len() {
let layout = self.levels[export_idx].clone();
let settings = self.settings.clone();
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let result = exporter::export_to_target(&layout, &settings, target);
let _ = tx.send(result);
});
self.export_rx = Some(rx);
}
let layouts = self.levels.clone();
let settings = self.settings.clone();
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let result = exporter::export_to_target(&layouts, &settings, target);
let _ = tx.send(result);
});
self.export_rx = Some(rx);
}
if let Some(rx) = &self.export_rx {
+8 -2
View File
@@ -432,14 +432,20 @@ fn draw_generate_tab(
let level_count = num_levels;
ui.horizontal(|ui| {
ui.label("Level");
let selected_text = if settings.export_level_index == 999 {
"All Levels".to_string()
} else {
format!("Level {}", settings.export_level_index + 1)
};
egui::ComboBox::from_id_salt("export_level")
.selected_text(format!("Level {}", settings.export_level_index))
.selected_text(selected_text)
.show_ui(ui, |ui| {
ui.selectable_value(&mut settings.export_level_index, 999, "All Levels");
for i in 0..level_count {
ui.selectable_value(
&mut settings.export_level_index,
i,
format!("Level {}", i),
format!("Level {}", i + 1),
);
}
});