aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/gui/constants/Position.java
blob: 144ba6d2a499ff9449a9d0d93ef975a86059e23b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package jcgp.gui.constants;

import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import jcgp.gui.GUI;
import jcgp.gui.population.GUIGene;
import jcgp.gui.population.GUIInput;
import jcgp.gui.population.GUINode;
import jcgp.gui.population.GUIOutput;

/**
 * Abstracts the task of positioning GUI components.
 * <br>
 * Do not instantiate this class; instead, use the {@code public static} methods provided.
 * 
 * @author Eduardo Pedroni
 *
 */
public final class Position {
	
	/**
	 * Private constructor to prevent instantiation.
	 */
	private Position() {}
	
	/**
	 * Sets the X and Y layouts of the specified input to the appropriate values, according to its index.
	 * 
	 * @param input the {@code GUIInput} instance to relocate.
	 */
	public static void place(GUIInput input) {
		// inputs are the first column, so we only worry about the margin and their index
		input.relocate(Constants.CHROMOSOME_PANE_MARGIN,
				input.getInput().getIndex() * (2 * Constants.NODE_RADIUS + Constants.SPACING) + Constants.CHROMOSOME_PANE_MARGIN);
	}
	
	/**
	 * Sets the X and Y layouts of the specified node to the appropriate values, according to its row and column values.
	 * This also connects the start of every line with its respective socket. Therefore, this method should be called at least
	 * once when the {@code GUINode} is instantiated.
	 * 
	 * @param node the {@code GUINode} instance to relocate.
	 */
	public static void place(GUINode node) {
		// calculate x and y offsets, in relation to the layout origin
		double xOffset = (node.getNode().getColumn() + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING) + Constants.CHROMOSOME_PANE_MARGIN;
		double yOffset = node.getNode().getRow() * (2 * Constants.NODE_RADIUS + Constants.SPACING) + Constants.CHROMOSOME_PANE_MARGIN;
		
		// move node
		node.relocate(xOffset, yOffset);
		
		// use the offset and the socket positions to connect the lines
		for (int i = 0; i < GUI.resources.arity(); i++) {
			node.getLine(i).setStartX(node.getSocket(i).getCenterX() + xOffset + Constants.NODE_RADIUS + Constants.SOCKET_RADIUS);
			node.getLine(i).setStartY(node.getSocket(i).getCenterY() + yOffset + Constants.NODE_RADIUS);
		}
	}
	
	/**
	 * Sets the X and Y layouts of the specified output to the appropriate values, according to its index.
	 * This also connects the start of the output's single line to its single input socket.Therefore,
	 * this method should be called at least once when the {@code GUIOutput} is instantiated.
	 * 
	 * @param output the {@code GUIOutput} instance to relocate.
	 */
	public static void place(GUIOutput output) {
		// the output's position is a function of the number of columns and its own index
		output.relocate(((GUI.resources.columns() + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.CHROMOSOME_PANE_MARGIN,
				output.getOutput().getIndex() * (2 * Constants.NODE_RADIUS + Constants.SPACING) + Constants.CHROMOSOME_PANE_MARGIN);
		output.getLine().setStartX(output.getLayoutX() - Constants.NODE_RADIUS);
		output.getLine().setStartY(output.getLayoutY());
	}
	
	
	
	/**
	 * Connects the end of a specified line to the specified gene.
	 * 
	 * @param line the line to connect.
	 * @param target the target gene to connect to.
	 */
	public static void connect(Line line, GUIGene target) {
		// set line ends based on the layout position of the target
		line.setEndX(target.getLayoutX() + Constants.NODE_RADIUS);
		line.setEndY(target.getLayoutY());
	}

	/**
	 * Relocates the given socket to the appropriate position given the 
	 * socket's index.
	 * 
	 * @param index the socket index.
	 * @param socket the {@code Circle} instance to relocate.
	 */
	public static void placeSocket(int index, Circle socket) {
		// calculate the angle with respect to the x-axis
		double angle = (((index + 1) / ((double) (GUI.resources.arity() + 1))) * Constants.THETA) - (Constants.THETA / 2);
		// convert to cartesian form
		double xPos = -Math.cos(angle) * Constants.NODE_RADIUS;
		double yPos = Math.sin(angle) * Constants.NODE_RADIUS;
		// set centre
		socket.setCenterX(xPos);
		socket.setCenterY(yPos);
	}
}