Can turn on a "horizontal wrap" setting
This commit is contained in:
		
							
								
								
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -146,7 +146,7 @@ dependencies = [
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "board-builder-gui"
 | 
			
		||||
version = "1.0.0"
 | 
			
		||||
version = "1.1.0"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "board-builder",
 | 
			
		||||
 "eframe",
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,9 @@ name = "board-builder-gui"
 | 
			
		||||
version = "1.1.0"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
 | 
			
		||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
board-builder = { path = "../" }
 | 
			
		||||
eframe = "0.18.0"
 | 
			
		||||
rfd = "0.8.2"
 | 
			
		||||
image = "0.24.2"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ use image::DynamicImage;
 | 
			
		||||
 | 
			
		||||
use rfd::FileDialog;
 | 
			
		||||
 | 
			
		||||
use board_builder::{ Board, Node, CoordTransformer, read_board_from_file, write_board_to_file };
 | 
			
		||||
use board_builder::{ Board, Node, CoordTransformer, read_board_from_file, write_board_to_file, should_wrap_horizontal };
 | 
			
		||||
 | 
			
		||||
use std::path::Path;
 | 
			
		||||
use std::collections::HashSet;
 | 
			
		||||
@@ -29,6 +29,7 @@ struct BoardBuilderApp {
 | 
			
		||||
    create_node_dialog: CreateNodeDialog,
 | 
			
		||||
    edit_node_dialog: EditNodeDialog,
 | 
			
		||||
    edit_labels_dialog: EditLabelsDialog,
 | 
			
		||||
    edit_settings_dialog: EditSettingsDialog,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Copy)]
 | 
			
		||||
@@ -93,7 +94,10 @@ impl eframe::App for BoardBuilderApp {
 | 
			
		||||
                    if ui.button("Edit Labels...").clicked() {
 | 
			
		||||
                        self.edit_labels_dialog.show(Rc::clone(&self.board));
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
                });
 | 
			
		||||
                if ui.button("Settings...").clicked() {
 | 
			
		||||
                    self.edit_settings_dialog.show(Rc::clone(&self.board));
 | 
			
		||||
                };
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        CentralPanel::default().show(ctx, |ui| {
 | 
			
		||||
@@ -121,6 +125,7 @@ impl eframe::App for BoardBuilderApp {
 | 
			
		||||
        self.create_node_dialog.ui(ctx);
 | 
			
		||||
        self.edit_node_dialog.ui(ctx);
 | 
			
		||||
        self.edit_labels_dialog.ui(ctx);
 | 
			
		||||
        self.edit_settings_dialog.ui(ctx);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -169,10 +174,25 @@ impl BoardBuilderApp {
 | 
			
		||||
            let stroke = Stroke { width: 1.0, color: Color32::BLACK };
 | 
			
		||||
            for edge in &node.edges {
 | 
			
		||||
                let other_node = &board.nodes[edge];
 | 
			
		||||
                painter.line_segment(
 | 
			
		||||
                    [view.inv_xform(node.x, node.y), view.inv_xform(other_node.x, other_node.y)],
 | 
			
		||||
                    stroke,
 | 
			
		||||
                );
 | 
			
		||||
                if board.config.horizontal_wrapping && should_wrap_horizontal(node, other_node) {
 | 
			
		||||
                    let mut nodes = [node, other_node];
 | 
			
		||||
                    nodes.sort_by(|a, b| a.x.partial_cmp(&b.x).unwrap());
 | 
			
		||||
                    let [left_node, right_node] = nodes;
 | 
			
		||||
                    let y_mid = (left_node.y + right_node.y) / 2.0;
 | 
			
		||||
                    painter.line_segment(
 | 
			
		||||
                        [view.inv_xform(0.0, y_mid), view.inv_xform(left_node.x, left_node.y)],
 | 
			
		||||
                        stroke
 | 
			
		||||
                    );
 | 
			
		||||
                    painter.line_segment(
 | 
			
		||||
                        [view.inv_xform(right_node.x, right_node.y), view.inv_xform(1.0, y_mid)],
 | 
			
		||||
                        stroke
 | 
			
		||||
                    );
 | 
			
		||||
                } else {
 | 
			
		||||
                    painter.line_segment(
 | 
			
		||||
                        [view.inv_xform(node.x, node.y), view.inv_xform(other_node.x, other_node.y)],
 | 
			
		||||
                        stroke,
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -364,7 +384,6 @@ impl EditLabelsDialog {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
struct StringDialog {
 | 
			
		||||
    string: String,
 | 
			
		||||
@@ -422,3 +441,26 @@ fn node_common_ui(ui: &mut Ui, node: &mut Node, board: &Board) {
 | 
			
		||||
            });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
struct EditSettingsDialog {
 | 
			
		||||
    open: bool,
 | 
			
		||||
    board: Rc<RefCell<Board>>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl EditSettingsDialog {
 | 
			
		||||
    fn show(&mut self, board: Rc<RefCell<Board>>) {
 | 
			
		||||
        self.board = board;
 | 
			
		||||
        self.open = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn ui(&mut self, ctx: &Context) {
 | 
			
		||||
        Window::new("Settings")
 | 
			
		||||
            .collapsible(false)
 | 
			
		||||
            .open(&mut self.open)
 | 
			
		||||
            .show(ctx, |ui| {
 | 
			
		||||
                let mut board = self.board.borrow_mut();
 | 
			
		||||
                ui.checkbox(&mut board.config.horizontal_wrapping, "Horizontal Wrapping");
 | 
			
		||||
            });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										29
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/lib.rs
									
									
									
									
									
								
							@@ -1,6 +1,18 @@
 | 
			
		||||
use serde::{ Serialize, Deserialize };
 | 
			
		||||
use std::collections::{ HashMap, HashSet };
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize, Deserialize, Debug)]
 | 
			
		||||
#[serde(default)]
 | 
			
		||||
pub struct Config {
 | 
			
		||||
    pub horizontal_wrapping: bool,
 | 
			
		||||
}
 | 
			
		||||
impl Default for Config {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        Config {
 | 
			
		||||
            horizontal_wrapping: false,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
 | 
			
		||||
#[serde(default)]
 | 
			
		||||
pub struct Node {
 | 
			
		||||
@@ -16,14 +28,9 @@ pub struct Node {
 | 
			
		||||
pub struct Board {
 | 
			
		||||
    pub labels: HashMap<String, HashSet<String>>,
 | 
			
		||||
    pub nodes: HashMap<usize, Node>,
 | 
			
		||||
    pub config: Config,
 | 
			
		||||
}
 | 
			
		||||
impl Board {
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
        let nodes = HashMap::new();
 | 
			
		||||
        let labels = HashMap::new();
 | 
			
		||||
        Board { nodes, labels }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn add_node(&mut self, x: f32, y: f32, name: String) {
 | 
			
		||||
        self.nodes.insert(self.next_id(), Node {
 | 
			
		||||
            x,
 | 
			
		||||
@@ -60,8 +67,8 @@ impl Board {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn add_edge(&mut self, from: usize, to: usize) {
 | 
			
		||||
	let node = self.nodes.get_mut(&from).expect("Could not find node");
 | 
			
		||||
	node.edges.insert(to);
 | 
			
		||||
	      let node = self.nodes.get_mut(&from).expect("Could not find node");
 | 
			
		||||
	      node.edges.insert(to);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn nearest_node(&self, x: f32, y: f32) -> Option<usize> {
 | 
			
		||||
@@ -97,6 +104,12 @@ fn dist_sq((x0, y0): (f32, f32), (x1, y1): (f32, f32)) -> f32 {
 | 
			
		||||
    (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn should_wrap_horizontal(node1: &Node, node2: &Node) -> bool {
 | 
			
		||||
    let mut xs = [node1.x, node2.x];
 | 
			
		||||
    xs.sort_by(|a, b| a.partial_cmp(b).unwrap());
 | 
			
		||||
    xs[0] + (1.0 - xs[1]) < xs[1] - xs[0]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
use std::io;
 | 
			
		||||
use std::io::{ Write, Read, Cursor };
 | 
			
		||||
use std::fs::File;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user