Remove nodes with right click

This commit is contained in:
Dane Johnson 2022-04-28 16:14:34 -05:00
parent 0c0cc7a01d
commit 3f76a78766

View File

@ -9,6 +9,8 @@ extern crate image;
use image::io::Reader as ImageReader; use image::io::Reader as ImageReader;
use image::{ DynamicImage }; use image::{ DynamicImage };
use std::collections::{HashMap, HashSet};
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -21,26 +23,61 @@ struct Node {
pub y: f32, pub y: f32,
pub name: String, pub name: String,
pub edges: Vec<usize>, pub edges: HashSet<usize>,
} }
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
struct Board { struct Board {
nodes: Vec<Node>, nodes: HashMap<usize, Node>,
} }
impl Board { impl Board {
pub fn new() -> Self { pub fn new() -> Self {
let nodes = Vec::new(); let nodes = HashMap::new();
Board { nodes } Board { nodes }
} }
pub fn add_node(&mut self, x: f32, y: f32) { pub fn add_node(&mut self, x: f32, y: f32) {
self.nodes.push(Node { self.nodes.insert(self.next_id(), Node {
x, x,
y, y,
name: "Canada".to_string(), name: "Canada".to_string(),
edges: vec![], edges: HashSet::new(),
}); });
} }
pub fn remove_node(&mut self, id: usize) {
self.nodes.remove(&id);
for (_, node) in &mut self.nodes {
node.edges.remove(&id);
}
}
pub fn nearest_node(&self, x: f32, y: f32) -> Option<usize> {
let f = |n: &Node| dist_sq((n.x, n.y), (x, y));
let mut iter = self.nodes.iter();
if let Some((id, node)) = iter.next() {
let mut min = *id;
let mut min_val = f(node);
for (id, node) in iter {
let val = f(node);
if val < min_val {
min = *id;
min_val = val;
}
}
Some(min)
} else {
None
}
}
fn next_id(&self) -> usize {
for i in 0 .. {
if !self.nodes.contains_key(&i) {
return i;
}
}
unreachable!();
}
} }
struct AppState { struct AppState {
@ -84,6 +121,10 @@ fn inv_lerp(v0: f32, v1: f32, a: f32) -> f32 {
(a - v0) / (v1 - v0) (a - v0) / (v1 - v0)
} }
fn dist_sq((x0, y0): (f32, f32), (x1, y1): (f32, f32)) -> f32 {
(x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)
}
trait CoordTransformer { trait CoordTransformer {
fn to_coords(&self, x: i32, y: i32) -> (f32, f32); fn to_coords(&self, x: i32, y: i32) -> (f32, f32);
fn from_coords(&self, x: f32, y: f32) -> (i32, i32); fn from_coords(&self, x: f32, y: f32) -> (i32, i32);
@ -200,7 +241,7 @@ fn main() {
image.draw(f.x(), f.y(), f.w(), f.h()); image.draw(f.x(), f.y(), f.w(), f.h());
} }
let board = &state.board; let board = &state.board;
for node in &board.nodes { for (_, node) in &board.nodes {
let (x, y) = f.from_coords(node.x, node.y); let (x, y) = f.from_coords(node.x, node.y);
draw_text(&node.name, x, y); draw_text(&node.name, x, y);
} }
@ -211,7 +252,14 @@ 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); state.board.add_node(pos_x, pos_y);
} 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(); app::redraw();
true true
} }