Selection modes
This commit is contained in:
parent
ad22b84cb1
commit
100366957b
83
src/main.rs
83
src/main.rs
@ -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();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user