Remove nodes with right click
This commit is contained in:
parent
0c0cc7a01d
commit
3f76a78766
62
src/main.rs
62
src/main.rs
@ -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());
|
||||||
state.board.add_node(pos_x, pos_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();
|
app::redraw();
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user