Selection modes

This commit is contained in:
Dane Johnson 2022-04-29 09:37:34 -05:00
parent ad22b84cb1
commit 100366957b

View File

@ -18,7 +18,6 @@ use std::io::{ Write, Read, Cursor };
use std::fs::File; use std::fs::File;
//////////////////// Data Layout //////////////////// //////////////////// Data Layout ////////////////////
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
@ -39,13 +38,13 @@ impl Board {
Board { nodes } Board { nodes }
} }
pub fn add_node(&mut self, x: f32, y: f32) { pub fn add_node(&mut self, x: f32, y: f32, name: String) {
self.nodes.insert(self.next_id(), Node { self.nodes.insert(self.next_id(), Node {
x, x,
y, y,
name: "Canada".to_string(), name,
edges: HashSet::new(), edges: HashSet::new(),
}); });
} }
pub fn remove_node(&mut self, id: usize) { pub fn remove_node(&mut self, id: usize) {
@ -134,29 +133,35 @@ impl CoordTransformer for frame::Frame {
} }
} }
fn menu_cb(_m: &mut impl MenuExt) {
todo!();
}
//////////////////// App State //////////////////// //////////////////// App State ////////////////////
enum EditMode {
Node,
Edge,
}
struct AppState { struct AppState {
pub board: Board, pub board: Board,
pub image_raw: Option<DynamicImage>, pub image_raw: Option<DynamicImage>,
pub image: Option<PngImage>, pub image: Option<PngImage>,
pub selected_node: Option<usize>,
pub edit_mode: EditMode,
} }
impl AppState { impl AppState {
fn new() -> Self { fn new() -> Self {
AppState { AppState {
board: Board::new(), board: Board::new(),
image_raw: None, image_raw: None,
image: None image: None,
selected_node: None,
edit_mode: EditMode::Node
} }
} }
} }
//////////////////// Procedural App Creation ////////////////////
fn main() { fn main() {
// App setup
let app = app::App::default() let app = app::App::default()
.with_scheme(app::Scheme::Gtk); .with_scheme(app::Scheme::Gtk);
let mut win = window::Window::default() let mut win = window::Window::default()
@ -168,23 +173,23 @@ fn main() {
// State // State
let state = Rc::new(RefCell::new(AppState::new())); let state = Rc::new(RefCell::new(AppState::new()));
// Menu // Menu
let mut menubar = menu::MenuBar::default(); let mut menubar = menu::MenuBar::default();
let state_clone = Rc::clone(&state); let state_clone = Rc::clone(&state);
menubar.add("File/New" , Shortcut::None, menu::MenuFlag::Normal, move |_| { menubar.add("File/New", Shortcut::None, menu::MenuFlag::Normal, move |_| {
state_clone.replace(AppState::new()); state_clone.replace(AppState::new());
app::redraw(); app::redraw();
}); });
let state_clone = Rc::clone(&state); let state_clone = Rc::clone(&state);
menubar.add("File/Open..." , Shortcut::None, menu::MenuFlag::Normal, move |_| { menubar.add("File/Open...", Shortcut::None, menu::MenuFlag::Normal, move |_| {
let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseFile); let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseFile);
fc.show(); fc.show();
let file = File::open(fc.filename()).unwrap(); let file = File::open(fc.filename()).unwrap();
let mut ar = zip::ZipArchive::new(file).unwrap(); let mut ar = zip::ZipArchive::new(file).unwrap();
let mut state = AppState::new(); let mut state = AppState::new();
let json_file = ar.by_name("graph.json").unwrap(); let json_file = ar.by_name("graph.json").unwrap();
state.board = serde_json::from_reader(json_file).unwrap(); state.board = serde_json::from_reader(json_file).unwrap();
if let Ok(mut image_file) = ar.by_name("image.png") { if let Ok(mut image_file) = ar.by_name("image.png") {
@ -199,7 +204,7 @@ fn main() {
state_clone.replace(state); state_clone.replace(state);
}); });
let state_clone = Rc::clone(&state); let state_clone = Rc::clone(&state);
menubar.add("File/Open Image..." , Shortcut::None, menu::MenuFlag::Normal, move |_| { menubar.add("File/Open Image...", Shortcut::None, menu::MenuFlag::Normal, move |_| {
let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseFile); let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseFile);
fc.show(); fc.show();
let filename = fc.filename(); let filename = fc.filename();
@ -216,7 +221,7 @@ fn main() {
} }
}); });
let state_clone = Rc::clone(&state); let state_clone = Rc::clone(&state);
menubar.add("File/Save As ..." , Shortcut::None, menu::MenuFlag::Normal, move |_| { menubar.add("File/Save As ...", Shortcut::None, menu::MenuFlag::Normal, move |_| {
let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseSaveFile); let mut fc = dialog::NativeFileChooser::new(dialog::NativeFileChooserType::BrowseSaveFile);
fc.show(); fc.show();
@ -224,7 +229,7 @@ fn main() {
let mut ar = zip::ZipWriter::new(file); let mut ar = zip::ZipWriter::new(file);
let options = zip::write::FileOptions::default(); let options = zip::write::FileOptions::default();
let state = state_clone.borrow(); let state = state_clone.borrow();
ar.start_file("graph.json", options).ok(); ar.start_file("graph.json", options).ok();
ar.write(&serde_json::to_vec(&state.board).unwrap()).ok(); ar.write(&serde_json::to_vec(&state.board).unwrap()).ok();
if let Some(image) = state.image_raw.as_ref() { if let Some(image) = state.image_raw.as_ref() {
@ -235,8 +240,17 @@ fn main() {
} }
ar.finish().ok(); ar.finish().ok();
}); });
menubar.add("Edit/Edit Nodes" , Shortcut::None, menu::MenuFlag::Normal, menu_cb); let state_clone = Rc::clone(&state);
menubar.add("Edit/Edit Edges" , Shortcut::None, menu::MenuFlag::Normal, menu_cb); menubar.add("Edit/Edit Nodes", Shortcut::None, menu::MenuFlag::Normal, move |_| {
let mut state = state_clone.borrow_mut();
state.edit_mode = EditMode::Node;
});
let state_clone = Rc::clone(&state);
menubar.add("Edit/Edit Edges", Shortcut::None, menu::MenuFlag::Normal, move |_| {
let mut state = state_clone.borrow_mut();
state.edit_mode = EditMode::Edge;
});
flex.set_size(&menubar, 40); flex.set_size(&menubar, 40);
// Canvas // Canvas
@ -262,26 +276,35 @@ fn main() {
Event::Push => { Event::Push => {
let mut state = state_clone.borrow_mut(); let mut state = state_clone.borrow_mut();
let (pos_x, pos_y) = f.to_coords(app::event_x(), app::event_y()); let (pos_x, pos_y) = f.to_coords(app::event_x(), app::event_y());
if app::event_button() == 1 {
state.board.add_node(pos_x, pos_y); match state.edit_mode {
} else if app::event_button() == 3 { EditMode::Node => {
let id = state.board.nearest_node(pos_x, pos_y); if app::event_button() == 1 {
if let Some(id) = id { let name = dialog::input_default("Node", "");
state.board.remove_node(id); if let Some(name) = name {
state.board.add_node(pos_x, pos_y, name);
}
} else if app::event_button() == 3 {
let id = state.board.nearest_node(pos_x, pos_y);
if let Some(id) = id {
state.board.remove_node(id);
}
}
app::redraw();
},
EditMode::Edge => {
todo!();
} }
} }
app::redraw();
true true
} }
_ => false, _ => false,
} }
}); });
flex.end();
flex.end();
win.end(); win.end();
win.make_resizable(true); win.make_resizable(true);
win.show(); win.show();
app.run().unwrap(); app.run().unwrap();
} }