View Javadoc
1   package io.github.magwas.inez.ui.mindmap.visuals;
2   
3   import org.eclipse.gef.fx.nodes.GeometryNode;
4   import org.eclipse.gef.geometry.planar.RoundedRectangle;
5   
6   import javafx.geometry.Insets;
7   import javafx.geometry.Orientation;
8   import javafx.geometry.VPos;
9   import javafx.scene.Group;
10  import javafx.scene.layout.Region;
11  import javafx.scene.layout.VBox;
12  import javafx.scene.paint.Color;
13  import javafx.scene.text.Text;
14  import javafx.scene.text.TextFlow;
15  
16  public class MindMapNodeVisual extends Region {
17  
18  	private static final double HORIZONTAL_PADDING = 20d;
19  	private static final double VERTICAL_PADDING = 10d;
20  	private static final double VERTICAL_SPACING = 5d;
21  
22  	private Text titleText;
23  	private TextFlow descriptionFlow;
24  	private Text descriptionText;
25  	private GeometryNode<RoundedRectangle> shape;
26  	private VBox labelVBox;
27  
28  	public MindMapNodeVisual() {
29  		// create background shape
30  		shape = new GeometryNode<>(new RoundedRectangle(0, 0, 70, 30, 8, 8));
31  		shape.setFill(Color.LIGHTGREEN);
32  		shape.setStroke(Color.BLACK);
33  
34  		// create vertical box for title and description
35  		labelVBox = new VBox(VERTICAL_SPACING);
36  		labelVBox.setPadding(new Insets(VERTICAL_PADDING, HORIZONTAL_PADDING,
37  				VERTICAL_PADDING, HORIZONTAL_PADDING));
38  
39  		// ensure shape and labels are resized to fit this visual
40  		shape.prefWidthProperty().bind(widthProperty());
41  		shape.prefHeightProperty().bind(heightProperty());
42  		labelVBox.prefWidthProperty().bind(widthProperty());
43  		labelVBox.prefHeightProperty().bind(heightProperty());
44  
45  		// create title text
46  		titleText = new Text();
47  		titleText.setTextOrigin(VPos.TOP);
48  
49  		// create description text
50  		descriptionText = new Text();
51  		descriptionText.setTextOrigin(VPos.TOP);
52  
53  		// use TextFlow to enable wrapping of the description text within the
54  		// label bounds
55  		descriptionFlow = new TextFlow(descriptionText);
56  		// only constrain the width, so that the height is computed in
57  		// dependence on the width
58  		descriptionFlow.maxWidthProperty()
59  				.bind(shape.widthProperty().subtract(HORIZONTAL_PADDING * 2));
60  
61  		// vertically lay out title and description
62  		labelVBox.getChildren().addAll(titleText, descriptionFlow);
63  
64  		// ensure title is always visible (see also #computeMinWidth(double) and
65  		// #computeMinHeight(double) methods)
66  		setMinSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE);
67  
68  		// wrap shape and VBox in Groups so that their bounds-in-parent is
69  		// considered when determining the layout-bounds of this visual
70  		getChildren().addAll(new Group(shape), new Group(labelVBox));
71  	}
72  
73  	@Override
74  	public double computeMinHeight(double width) {
75  		// ensure title is always visible
76  		// descriptionFlow.minHeight(width) +
77  		// titleText.getLayoutBounds().getHeight() + VERTICAL_PADDING * 2;
78  		return labelVBox.minHeight(width);
79  	}
80  
81  	@Override
82  	public double computeMinWidth(double height) {
83  		// ensure title is always visible
84  		return titleText.getLayoutBounds().getWidth() + HORIZONTAL_PADDING * 2;
85  	}
86  
87  	@Override
88  	protected double computePrefHeight(double width) {
89  		return minHeight(width);
90  	}
91  
92  	@Override
93  	protected double computePrefWidth(double height) {
94  		return minWidth(height);
95  	}
96  
97  	@Override
98  	public Orientation getContentBias() {
99  		return Orientation.HORIZONTAL;
100 	}
101 
102 	public Text getDescriptionText() {
103 		return descriptionText;
104 	}
105 
106 	public GeometryNode<?> getGeometryNode() {
107 		return shape;
108 	}
109 
110 	public Text getTitleText() {
111 		return titleText;
112 	}
113 
114 	public void setColor(Color color) {
115 		shape.setFill(color);
116 	}
117 
118 	public void setDescription(String description) {
119 		this.descriptionText.setText(description);
120 	}
121 
122 	public void setTitle(String title) {
123 		this.titleText.setText(title);
124 	}
125 }