diff --git a/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java
index 320a38b688..c92097077a 100644
--- a/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java
+++ b/core/src/io/anuke/mindustry/ui/dialogs/DeployDialog.java
@@ -23,7 +23,8 @@ import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.io.SaveIO.*;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.*;
-import io.anuke.mindustry.ui.TreeLayout.*;
+import io.anuke.mindustry.ui.layout.*;
+import io.anuke.mindustry.ui.layout.TreeLayout.*;
import static io.anuke.mindustry.Vars.*;
@@ -39,7 +40,7 @@ public class DeployDialog extends FloatingDialog{
ZoneNode root = new ZoneNode(Zones.groundZero, null);
- TreeLayout layout = new TreeLayout();
+ BranchTreeLayout layout = new BranchTreeLayout();
layout.gapBetweenLevels = layout.gapBetweenNodes = Scl.scl(60f);
layout.gapBetweenNodes = Scl.scl(120f);
layout.layout(root);
diff --git a/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java
index 5318077305..b34b4935eb 100644
--- a/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java
+++ b/core/src/io/anuke/mindustry/ui/dialogs/TechTreeDialog.java
@@ -22,7 +22,8 @@ import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.ui.*;
-import io.anuke.mindustry.ui.TreeLayout.*;
+import io.anuke.mindustry.ui.layout.*;
+import io.anuke.mindustry.ui.layout.TreeLayout.*;
import static io.anuke.mindustry.Vars.*;
@@ -101,13 +102,10 @@ public class TechTreeDialog extends FloatingDialog{
}
void treeLayout(){
- TreeLayout layout = new TreeLayout();
- layout.gapBetweenLevels = Scl.scl(60f);
- layout.gapBetweenNodes = Scl.scl(40f);
+ RadialTreeLayout layout = new RadialTreeLayout();
LayoutNode node = new LayoutNode(root, null);
layout.layout(node);
- bounds.set(layout.getBounds());
- bounds.y += nodeSize*1.5f;
+ //bounds.y += nodeSize*1.5f;
copyInfo(node);
}
@@ -156,7 +154,7 @@ public class TechTreeDialog extends FloatingDialog{
this.parent = parent;
this.width = this.height = nodeSize;
if(node.children != null){
- children = Array.with(node.children).select(n -> n.visible).map(t -> new LayoutNode(t, this)).toArray(LayoutNode.class);
+ children = Array.with(node.children).map(t -> new LayoutNode(t, this)).toArray(LayoutNode.class);
}
}
}
diff --git a/core/src/io/anuke/mindustry/ui/TreeLayout.java b/core/src/io/anuke/mindustry/ui/layout/BranchTreeLayout.java
similarity index 95%
rename from core/src/io/anuke/mindustry/ui/TreeLayout.java
rename to core/src/io/anuke/mindustry/ui/layout/BranchTreeLayout.java
index 7e373ba231..5f3f4b6932 100644
--- a/core/src/io/anuke/mindustry/ui/TreeLayout.java
+++ b/core/src/io/anuke/mindustry/ui/layout/BranchTreeLayout.java
@@ -1,4 +1,4 @@
-package io.anuke.mindustry.ui;
+package io.anuke.mindustry.ui.layout;
import io.anuke.arc.collection.*;
import io.anuke.arc.math.geom.*;
@@ -6,7 +6,7 @@ import io.anuke.arc.math.geom.*;
/**
* Algorithm taken from TreeLayout.
*/
-public class TreeLayout{
+public class BranchTreeLayout implements TreeLayout{
public TreeLocation rootLocation = TreeLocation.top;
public TreeAlignment alignment = TreeAlignment.awayFromRoot;
public float gapBetweenLevels = 10;
@@ -18,6 +18,7 @@ public class TreeLayout{
private float boundsTop = Float.MAX_VALUE;
private float boundsBottom = Float.MIN_VALUE;
+ @Override
public void layout(TreeNode root){
firstWalk(root, null);
calcSizeOfLevels(root, 0);
@@ -288,20 +289,4 @@ public class TreeLayout{
public enum TreeAlignment{
center, towardsRoot, awayFromRoot
}
-
- public static class TreeNode{
- public float width, height, x, y;
-
- //should be initialized by user
- public T[] children;
- public T parent;
-
- private float mode, prelim, change, shift;
- private int number = -1;
- private TreeNode thread, ancestor;
-
- boolean isLeaf(){
- return children == null || children.length == 0;
- }
- }
}
\ No newline at end of file
diff --git a/core/src/io/anuke/mindustry/ui/layout/RadialTreeLayout.java b/core/src/io/anuke/mindustry/ui/layout/RadialTreeLayout.java
new file mode 100644
index 0000000000..8628c1886c
--- /dev/null
+++ b/core/src/io/anuke/mindustry/ui/layout/RadialTreeLayout.java
@@ -0,0 +1,65 @@
+package io.anuke.mindustry.ui.layout;
+
+import io.anuke.arc.collection.*;
+import io.anuke.arc.math.*;
+
+public class RadialTreeLayout implements TreeLayout{
+ public float startRadius, delta;
+
+ @Override
+ public void layout(TreeNode root){
+ startRadius = root.height * 2.4f;
+ delta = root.height * 2.4f;
+
+ bfs(root, true);
+ radialize(root, 0, 360);
+ }
+
+ void radialize(TreeNode root, float from, float to){
+ int depthOfVertex = root.number;
+ float theta = from;
+ float radius = startRadius + (delta * depthOfVertex);
+
+ int leavesNumber = bfs(root, false);
+ for(TreeNode child : root.children){
+ int lambda = bfs(child, false);
+ float mi = theta + ((float)lambda / leavesNumber * (to - from));
+
+ float x = radius * Mathf.cos((theta + mi) / 2f * Mathf.degRad);
+ float y = radius * Mathf.sin((theta + mi) / 2f * Mathf.degRad);
+
+ child.x = x;
+ child.y = y;
+
+ if(child.children.length > 0){
+ radialize(child, theta, mi);
+ }
+ theta = mi;
+ }
+ }
+
+ int bfs(TreeNode node, boolean assign){
+ if(assign) node.number = 0;
+ ObjectSet visited = new ObjectSet<>();
+ Queue queue = new Queue<>();
+ int leaves = 0;
+
+ visited.add(node);
+ queue.addFirst(node);
+
+ while(!queue.isEmpty()){
+ TreeNode current = queue.removeFirst();
+ if(current.children.length == 0) leaves++;
+
+ for(TreeNode child : current.children){
+ if(assign) child.number = current.number + 1;
+ if(!visited.contains(child)){
+ visited.add(child);
+ queue.addLast(child);
+ }
+ }
+ }
+
+ return leaves;
+ }
+}
diff --git a/core/src/io/anuke/mindustry/ui/layout/TreeLayout.java b/core/src/io/anuke/mindustry/ui/layout/TreeLayout.java
new file mode 100644
index 0000000000..ba904f69c9
--- /dev/null
+++ b/core/src/io/anuke/mindustry/ui/layout/TreeLayout.java
@@ -0,0 +1,22 @@
+package io.anuke.mindustry.ui.layout;
+
+public interface TreeLayout{
+ void layout(TreeNode root);
+
+ class TreeNode{
+ public float width, height, x, y;
+
+ //should be initialized by user
+ public T[] children;
+ public T parent;
+
+ //internal stuff
+ public float mode, prelim, change, shift;
+ public int number = -1, ancestors;
+ public TreeNode thread, ancestor;
+
+ public boolean isLeaf(){
+ return children == null || children.length == 0;
+ }
+ }
+}