Skip to content

Commit 49db235

Browse files
committed
Merge pull request #167 from ProgrammingLife2016/dev-new
Dev new
2 parents a2c14f0 + b3508d2 commit 49db235

File tree

18 files changed

+609
-132
lines changed

18 files changed

+609
-132
lines changed

PL2/PL2-gui/src/main/java/nl/tudelft/pl2016gr2/gui/model/IPhylogeneticTreeRoot.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package nl.tudelft.pl2016gr2.gui.model;
22

3+
import java.util.Collection;
4+
35
/**
46
* This interface must be implemented by the root of the phylogenetic tree.
57
*
@@ -28,8 +30,8 @@ public interface IPhylogeneticTreeRoot extends IPhylogeneticTreeNode {
2830
/**
2931
* Highlight a path in the phylogenetic tree.
3032
*
31-
* @param oldPath the previously highlighted path.
32-
* @param newPath the new highlighted path.
33+
* @param oldPath the previously highlighted paths.
34+
* @param newPath the new highlighted paths.
3335
*/
34-
void highlightPath(int oldPath, int newPath);
36+
void highlightPaths(Collection<Integer> oldPath, Collection<Integer> newPath);
3537
}

PL2/PL2-gui/src/main/java/nl/tudelft/pl2016gr2/gui/model/PhylogeneticTreeNode.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,15 +287,19 @@ private void setLineageColor(LineageColor lineageColor) {
287287
*/
288288
protected void unhighlightPath() {
289289
inHighlightedPath.set(false);
290-
parent.unhighlightPath();
290+
if (parent != null) {
291+
parent.unhighlightPath();
292+
}
291293
}
292294

293295
/**
294296
* Highlight this tree node.
295297
*/
296298
protected void highlightPath() {
297299
inHighlightedPath.set(true);
298-
parent.highlightPath();
300+
if (parent != null) {
301+
parent.highlightPath();
302+
}
299303
}
300304

301305
/**

PL2/PL2-gui/src/main/java/nl/tudelft/pl2016gr2/gui/model/PhylogeneticTreeRoot.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import nl.tudelft.pl2016gr2.model.Annotation;
55
import nl.tudelft.pl2016gr2.model.GenomeMap;
66

7+
import java.util.Collection;
78
import java.util.HashMap;
89
import java.util.List;
910

@@ -59,14 +60,18 @@ public void setDrawnInBottom(int genome, boolean isDrawn) {
5960
}
6061

6162
@Override
62-
public void highlightPath(int oldPath, int newPath) {
63-
PhylogeneticTreeNode oldSelection = genomeToTreeMap.get(oldPath);
64-
PhylogeneticTreeNode newSelection = genomeToTreeMap.get(newPath);
65-
if (oldSelection != null) {
66-
oldSelection.unhighlightPath();
63+
public void highlightPaths(Collection<Integer> oldPaths, Collection<Integer> newPaths) {
64+
for (Integer oldPath : oldPaths) {
65+
PhylogeneticTreeNode oldSelection = genomeToTreeMap.get(oldPath);
66+
if (oldSelection != null) {
67+
oldSelection.unhighlightPath();
68+
}
6769
}
68-
if (newSelection != null) {
69-
newSelection.highlightPath();
70+
for (Integer newPath : newPaths) {
71+
PhylogeneticTreeNode newSelection = genomeToTreeMap.get(newPath);
72+
if (newSelection != null) {
73+
newSelection.highlightPath();
74+
}
7075
}
7176
}
7277
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package nl.tudelft.pl2016gr2.gui.view;
2+
3+
import javafx.collections.ObservableList;
4+
import javafx.fxml.FXML;
5+
import javafx.fxml.Initializable;
6+
import javafx.geometry.Pos;
7+
import javafx.scene.Node;
8+
import javafx.scene.control.Label;
9+
import javafx.scene.control.Tooltip;
10+
import javafx.scene.layout.AnchorPane;
11+
import javafx.scene.layout.HBox;
12+
import javafx.scene.layout.Pane;
13+
import javafx.scene.layout.StackPane;
14+
15+
import java.net.URL;
16+
import java.util.ResourceBundle;
17+
18+
public class LegendController implements Initializable {
19+
20+
@FXML
21+
private Node toggle;
22+
23+
@FXML
24+
private Label title;
25+
26+
@FXML
27+
private Pane legendItemContainer;
28+
29+
@FXML
30+
private Node legendItemContainerWrapper;
31+
32+
@Override
33+
public void initialize(URL location, ResourceBundle resources) {
34+
toggle.setOnMouseClicked(event -> {
35+
legendItemContainerWrapper.setVisible(!legendItemContainerWrapper.isVisible());
36+
});
37+
}
38+
39+
/**
40+
* Setup the legend with actual data.
41+
*
42+
* @param title title above the legend.
43+
* @param toggleX x offset of toggle, positive for top, negative for bottom.
44+
* @param toggleY xyoffset of toggle, positive for left, negative for right.
45+
* @param items Items to show.
46+
*/
47+
public void initializeData(String title, double toggleX, double toggleY, LegendItem ... items) {
48+
this.title.setText(title);
49+
50+
setTogglePosition(toggleX, toggleY);
51+
52+
ObservableList<Node> children = legendItemContainer.getChildren();
53+
for (LegendItem item : items) {
54+
children.add(buildNodeForItem(item));
55+
}
56+
}
57+
58+
private void setTogglePosition(double toggleX, double toggleY) {
59+
if (toggleX > 0) {
60+
AnchorPane.setLeftAnchor(toggle, toggleX);
61+
} else {
62+
AnchorPane.setRightAnchor(toggle, -toggleX);
63+
}
64+
if (toggleY > 0) {
65+
AnchorPane.setTopAnchor(toggle, toggleY);
66+
} else {
67+
AnchorPane.setBottomAnchor(toggle, -toggleY);
68+
}
69+
}
70+
71+
private static Node buildNodeForItem(LegendItem item) {
72+
StackPane symbolPane = new StackPane(item.node);
73+
symbolPane.setPrefWidth(50.0);
74+
symbolPane.setPrefHeight(25.0);
75+
symbolPane.setAlignment(Pos.CENTER);
76+
77+
StackPane textPane = new StackPane(new Label(item.shortDescription));
78+
textPane.setPrefHeight(25.0);
79+
textPane.setAlignment(Pos.CENTER_LEFT);
80+
81+
HBox hBox = new HBox(symbolPane, textPane);
82+
hBox.setAlignment(Pos.BASELINE_LEFT);
83+
Tooltip.install(hBox, new Tooltip(item.description));
84+
return hBox;
85+
}
86+
87+
protected static class LegendItem {
88+
89+
final String description;
90+
final String shortDescription;
91+
final Node node;
92+
93+
public LegendItem(String description, String shortDescription, Node node) {
94+
this.description = description;
95+
this.shortDescription = shortDescription;
96+
this.node = node;
97+
}
98+
99+
}
100+
}

PL2/PL2-gui/src/main/java/nl/tudelft/pl2016gr2/gui/view/RootLayoutController.java

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
package nl.tudelft.pl2016gr2.gui.view;
22

3+
import javafx.beans.value.ChangeListener;
4+
import javafx.beans.value.ObservableValue;
35
import javafx.fxml.FXML;
46
import javafx.fxml.FXMLLoader;
57
import javafx.fxml.Initializable;
8+
import javafx.scene.Scene;
69
import javafx.scene.control.SplitPane;
10+
import javafx.scene.input.KeyEvent;
711
import javafx.scene.input.MouseEvent;
812
import javafx.scene.layout.AnchorPane;
913
import javafx.scene.layout.Pane;
1014
import javafx.scene.layout.Region;
15+
import javafx.scene.paint.Color;
16+
import javafx.scene.shape.Circle;
17+
import javafx.scene.shape.Rectangle;
1118
import net.sourceforge.olduvai.treejuxtaposer.drawer.Tree;
1219
import nl.tudelft.pl2016gr2.core.GraphFactory;
1320
import nl.tudelft.pl2016gr2.core.InputStreamGraphFactory;
1421
import nl.tudelft.pl2016gr2.core.InputStreamTreeFactory;
1522
import nl.tudelft.pl2016gr2.core.TreeFactory;
23+
import nl.tudelft.pl2016gr2.gui.model.LineageColor;
1624
import nl.tudelft.pl2016gr2.gui.model.PhylogeneticTreeRoot;
1725
import nl.tudelft.pl2016gr2.gui.view.graph.DrawComparedGraphs;
1826
import nl.tudelft.pl2016gr2.gui.view.selection.SelectionManager;
@@ -28,6 +36,7 @@
2836
import java.net.URL;
2937
import java.util.ArrayList;
3038
import java.util.List;
39+
import java.util.Locale;
3140
import java.util.ResourceBundle;
3241
import java.util.logging.Level;
3342
import java.util.logging.Logger;
@@ -47,6 +56,15 @@ public class RootLayoutController implements
4756
private Pane selectionDescriptionPane;
4857
@FXML
4958
private SplitPane mainPane;
59+
@FXML
60+
private LegendController graphLegendController;
61+
@FXML
62+
private LegendController treeLegendController;
63+
64+
@FXML
65+
private Pane searchPane;
66+
@FXML
67+
private SearchPaneController searchPaneController;
5068

5169
@TestId(id = "treeManager")
5270
private TreeManager treeManager;
@@ -65,6 +83,7 @@ public class RootLayoutController implements
6583
@Override
6684
public void initialize(URL location, ResourceBundle resources) {
6785
initializeSelectionManager();
86+
initializeLegend();
6887
treeManager = TreeManager.loadView(selectionManager);
6988
drawGraphs = DrawComparedGraphs.loadView(selectionManager);
7089
mainPane.getItems().add(treeManager.getTreePane());
@@ -73,6 +92,18 @@ public void initialize(URL location, ResourceBundle resources) {
7392
mainPane.getItems().add(graphRegion);
7493
graphRegion.prefHeightProperty().bind(mainPane.heightProperty());
7594
mainPane.setDividerPosition(0, 0.35);
95+
96+
rootPane.sceneProperty().addListener(new ChangeListener<Scene>() {
97+
@Override
98+
public void changed(ObservableValue<? extends Scene> observable, Scene oldValue,
99+
Scene newValue) {
100+
if (newValue != null) {
101+
initializeSearchPaneController();
102+
// fire this only once when scene is set.
103+
rootPane.sceneProperty().removeListener(this);
104+
}
105+
}
106+
});
76107
}
77108

78109
/**
@@ -144,6 +175,60 @@ private void initializeSelectionManager() {
144175
});
145176
}
146177

178+
@SuppressWarnings("checkstyle:methodlength")
179+
private void initializeLegend() {
180+
graphLegendController.initializeData(
181+
"Legend",
182+
-5.0, 5.0,
183+
new LegendController.LegendItem(
184+
"This element represent a bubble.",
185+
"Bubble",
186+
new Rectangle(20, 20, Color.ALICEBLUE)),
187+
new LegendController.LegendItem(
188+
"This element represents a sequence.",
189+
"Different sequence",
190+
new Circle(10, Color.rgb(0, 73, 73))),
191+
new LegendController.LegendItem(
192+
"This element represents a sequence.",
193+
"Equal sequence",
194+
new Circle(10, Color.rgb(146, 0, 0))));
195+
196+
197+
List<LegendController.LegendItem> treeLegendItems = new ArrayList<>();
198+
for (LineageColor color : LineageColor.values()) {
199+
treeLegendItems.add(new LegendController.LegendItem(
200+
String.format("Lineage color %s", color.name()),
201+
color.name(),
202+
new Rectangle(20, 5, color.getColor())
203+
));
204+
}
205+
206+
treeLegendController.initializeData(
207+
"Legend",
208+
10.0, 5.0,
209+
treeLegendItems.toArray(new LegendController.LegendItem[treeLegendItems.size()]));
210+
211+
}
212+
213+
private void initializeSearchPaneController() {
214+
String os = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
215+
boolean isOSx = os.contains("mac") || os.contains("darwin");
216+
217+
rootPane.getScene().addEventFilter(KeyEvent.KEY_PRESSED, keyEvent -> {
218+
System.out.println("KEYEVENT");
219+
switch (keyEvent.getCode()) {
220+
case F:
221+
if (keyEvent.isControlDown() || isOSx && keyEvent.isMetaDown()) {
222+
searchPane.setVisible(!searchPane.isVisible());
223+
keyEvent.consume();
224+
}
225+
break;
226+
default:
227+
}
228+
});
229+
searchPaneController.setSelectionManager(selectionManager);
230+
}
231+
147232
@Override
148233
public void filesLoaded(InputStream treeFile, InputStream graphFile, InputStream metadataFile) {
149234
try {
@@ -154,10 +239,12 @@ public void filesLoaded(InputStream treeFile, InputStream graphFile, InputStream
154239

155240
SequenceGraph graph = graphFactory.getGraph();
156241
Tree tree = treeFactory.getTree();
242+
List<Annotation> annotations = new AnnotationReader(metadataFile).read();
157243

158244
if (graph != null && tree != null) {
159245
loadGraph(graph);
160-
loadTree(tree, new AnnotationReader(metadataFile).read());
246+
loadTree(tree, annotations);
247+
searchPaneController.setData(annotations);
161248
} else {
162249
Logger.getLogger(RootLayoutController.class.getName()).log(
163250
Level.SEVERE,

0 commit comments

Comments
 (0)