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; + } + } +}