save dialog, n=tabs y=spaces
This commit is contained in:
@@ -5,7 +5,7 @@ use image::DynamicImage;
|
||||
|
||||
use rfd::FileDialog;
|
||||
|
||||
use board_builder::{ Board, CoordTransformer, read_board_from_file };
|
||||
use board_builder::{ Board, CoordTransformer, read_board_from_file, write_board_to_file };
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
@@ -23,104 +23,106 @@ struct BoardBuilderApp {
|
||||
|
||||
impl eframe::App for BoardBuilderApp {
|
||||
fn update(&mut self, ctx: &Context, _frame: &mut eframe::Frame) {
|
||||
TopBottomPanel::top("menubar").show(ctx, |ui| {
|
||||
menu::bar(ui, |ui| {
|
||||
fn choose_file() {
|
||||
FileDialog::new().pick_file();
|
||||
}
|
||||
ui.menu_button("File", |ui| {
|
||||
ui.button("New");
|
||||
if ui.button("Open...").clicked() {
|
||||
if let Some(board_file) = FileDialog::new().pick_file() {
|
||||
match read_board_from_file(&board_file) {
|
||||
Ok((board, image)) => {
|
||||
self.board = board;
|
||||
match image {
|
||||
None => { self.image = None; self.texture = None }
|
||||
Some(image) => self.load_image(ctx, image),
|
||||
}
|
||||
}
|
||||
Err(_) => panic!("Could not open file!"),
|
||||
}
|
||||
}
|
||||
}
|
||||
if ui.button("Save As...").clicked() {
|
||||
choose_file();
|
||||
}
|
||||
if ui.button("Open Image...").clicked() {
|
||||
let image_file = FileDialog::new()
|
||||
.add_filter("Image", &["png", "jpg", "jpeg", "gif", "webp", "bmp", "tiff"])
|
||||
.pick_file();
|
||||
if let Some(image_file) = image_file {
|
||||
self.load_image_file(ctx, &image_file);
|
||||
}
|
||||
}
|
||||
});
|
||||
ui.menu_button("Edit", |ui| {
|
||||
ui.button("Edit Nodes");
|
||||
ui.button("Edit Edges");
|
||||
ui.button("Edit Labels...");
|
||||
})
|
||||
});
|
||||
});
|
||||
CentralPanel::default().show(ctx, |ui| {
|
||||
if let Some(texture) = self.texture.as_ref() {
|
||||
let size = ui.available_size();
|
||||
let (response, painter) = ui.allocate_painter(size, Sense::click());
|
||||
let image = widgets::Image::new(texture, size);
|
||||
image.paint_at(ui, response.rect);
|
||||
let view = View(response.rect);
|
||||
self.draw_board(&painter, view);
|
||||
}
|
||||
});
|
||||
TopBottomPanel::top("menubar").show(ctx, |ui| {
|
||||
menu::bar(ui, |ui| {
|
||||
fn choose_file() {
|
||||
FileDialog::new().pick_file();
|
||||
}
|
||||
ui.menu_button("File", |ui| {
|
||||
ui.button("New");
|
||||
if ui.button("Open...").clicked() {
|
||||
if let Some(board_file) = FileDialog::new().pick_file() {
|
||||
match read_board_from_file(&board_file) {
|
||||
Ok((board, image)) => {
|
||||
self.board = board;
|
||||
match image {
|
||||
None => { self.image = None; self.texture = None }
|
||||
Some(image) => self.load_image(ctx, image),
|
||||
}
|
||||
}
|
||||
Err(_) => panic!("Could not open file!"),
|
||||
}
|
||||
}
|
||||
}
|
||||
if ui.button("Save As...").clicked() {
|
||||
if let Some(board_file) = FileDialog::new().save_file() {
|
||||
write_board_to_file(&self.board, self.image.as_ref(), &board_file);
|
||||
}
|
||||
}
|
||||
if ui.button("Open Image...").clicked() {
|
||||
let image_file = FileDialog::new()
|
||||
.add_filter("Image", &["png", "jpg", "jpeg", "gif", "webp", "bmp", "tiff"])
|
||||
.pick_file();
|
||||
if let Some(image_file) = image_file {
|
||||
self.load_image_file(ctx, &image_file);
|
||||
}
|
||||
}
|
||||
});
|
||||
ui.menu_button("Edit", |ui| {
|
||||
ui.button("Edit Nodes");
|
||||
ui.button("Edit Edges");
|
||||
ui.button("Edit Labels...");
|
||||
})
|
||||
});
|
||||
});
|
||||
CentralPanel::default().show(ctx, |ui| {
|
||||
if let Some(texture) = self.texture.as_ref() {
|
||||
let size = ui.available_size();
|
||||
let (response, painter) = ui.allocate_painter(size, Sense::click());
|
||||
let image = widgets::Image::new(texture, size);
|
||||
image.paint_at(ui, response.rect);
|
||||
let view = View(response.rect);
|
||||
self.draw_board(&painter, view);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl BoardBuilderApp {
|
||||
fn new(cc: &eframe::CreationContext<'_>) -> Self {
|
||||
let mut style = (*cc.egui_ctx.style()).clone();
|
||||
let mut button = style::TextStyle::Button.resolve(&style);
|
||||
button.size = 20.0;
|
||||
style.text_styles.insert(style::TextStyle::Button, button);
|
||||
cc.egui_ctx.set_style(style);
|
||||
|
||||
|
||||
BoardBuilderApp::default()
|
||||
let mut style = (*cc.egui_ctx.style()).clone();
|
||||
let mut button = style::TextStyle::Button.resolve(&style);
|
||||
button.size = 20.0;
|
||||
style.text_styles.insert(style::TextStyle::Button, button);
|
||||
cc.egui_ctx.set_style(style);
|
||||
|
||||
|
||||
BoardBuilderApp::default()
|
||||
}
|
||||
fn load_image_file(&mut self, ctx: &Context, image_file: &Path) -> Result<(), image::ImageError> {
|
||||
let image = image::io::Reader::open(image_file)?.decode()?;
|
||||
self.load_image(ctx, image);
|
||||
Ok(())
|
||||
let image = image::io::Reader::open(image_file)?.decode()?;
|
||||
self.load_image(ctx, image);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn load_image(&mut self, ctx: &Context, image: DynamicImage) {
|
||||
let egui_image = egui::ColorImage::from_rgba_unmultiplied(
|
||||
[image.width() as _, image.height() as _],
|
||||
image.to_rgba8().as_flat_samples().as_slice(),
|
||||
);
|
||||
|
||||
self.image = Some(image);
|
||||
self.texture = Some(ctx.load_texture("board-image", egui_image));
|
||||
let egui_image = egui::ColorImage::from_rgba_unmultiplied(
|
||||
[image.width() as _, image.height() as _],
|
||||
image.to_rgba8().as_flat_samples().as_slice(),
|
||||
);
|
||||
|
||||
self.image = Some(image);
|
||||
self.texture = Some(ctx.load_texture("board-image", egui_image));
|
||||
}
|
||||
|
||||
fn draw_board(&self, painter: &Painter, view: View) {
|
||||
for node in self.board.nodes.values() {
|
||||
painter.text(
|
||||
view.from_coords(node.x, node.y),
|
||||
Align2::CENTER_CENTER,
|
||||
&node.name,
|
||||
FontId::proportional(16.0),
|
||||
Color32::BLACK,
|
||||
);
|
||||
let stroke = Stroke { width: 1.0, color: Color32::BLACK };
|
||||
for edge in &node.edges {
|
||||
let other_node = &self.board.nodes[edge];
|
||||
painter.line_segment(
|
||||
[view.from_coords(node.x, node.y), view.from_coords(other_node.x, other_node.y)],
|
||||
stroke,
|
||||
);
|
||||
}
|
||||
}
|
||||
for node in self.board.nodes.values() {
|
||||
painter.text(
|
||||
view.from_coords(node.x, node.y),
|
||||
Align2::CENTER_CENTER,
|
||||
&node.name,
|
||||
FontId::proportional(16.0),
|
||||
Color32::BLACK,
|
||||
);
|
||||
let stroke = Stroke { width: 1.0, color: Color32::BLACK };
|
||||
for edge in &node.edges {
|
||||
let other_node = &self.board.nodes[edge];
|
||||
painter.line_segment(
|
||||
[view.from_coords(node.x, node.y), view.from_coords(other_node.x, other_node.y)],
|
||||
stroke,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user