Remove nodes with right click
This commit is contained in:
parent
0c0cc7a01d
commit
3f76a78766
60
src/main.rs
60
src/main.rs
@ -9,6 +9,8 @@ extern crate image;
|
||||
use image::io::Reader as ImageReader;
|
||||
use image::{ DynamicImage };
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -21,26 +23,61 @@ struct Node {
|
||||
pub y: f32,
|
||||
|
||||
pub name: String,
|
||||
pub edges: Vec<usize>,
|
||||
pub edges: HashSet<usize>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct Board {
|
||||
nodes: Vec<Node>,
|
||||
nodes: HashMap<usize, Node>,
|
||||
}
|
||||
impl Board {
|
||||
pub fn new() -> Self {
|
||||
let nodes = Vec::new();
|
||||
let nodes = HashMap::new();
|
||||
Board { nodes }
|
||||
}
|
||||
|
||||
pub fn add_node(&mut self, x: f32, y: f32) {
|
||||
self.nodes.push(Node {
|
||||
self.nodes.insert(self.next_id(), Node {
|
||||
x,
|
||||
y,
|
||||
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 {
|
||||
@ -84,6 +121,10 @@ fn inv_lerp(v0: f32, v1: f32, a: f32) -> f32 {
|
||||
(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 {
|
||||
fn to_coords(&self, x: i32, y: i32) -> (f32, f32);
|
||||
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());
|
||||
}
|
||||
let board = &state.board;
|
||||
for node in &board.nodes {
|
||||
for (_, node) in &board.nodes {
|
||||
let (x, y) = f.from_coords(node.x, node.y);
|
||||
draw_text(&node.name, x, y);
|
||||
}
|
||||
@ -211,7 +252,14 @@ fn main() {
|
||||
Event::Push => {
|
||||
let mut state = state_clone.borrow_mut();
|
||||
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);
|
||||
} 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();
|
||||
true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user