tree.d 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. module renderable.tree;
  2. import app;
  3. import renderable.rect;
  4. import renderable.renderable;
  5. import vector;
  6. import color;
  7. import cell;
  8. import std.stdio;
  9. import std.algorithm;
  10. import renderable.cellcachecontainer;
  11. import stacklayouttype;
  12. import std.format;
  13. import renderable.label;
  14. import renderable.rect;
  15. import stacklayouttype;
  16. import renderable.stacklayout;
  17. import horizontaltextalignment;
  18. import verticaltextalignment;
  19. import std.conv;
  20. struct Node {
  21. string label = "Node";
  22. Node[] children;
  23. protected int level = 0;
  24. this(string label, Node[] children...) {
  25. this(children);
  26. this.label = label;
  27. }
  28. this(Node[] children...) {
  29. this.children = children;
  30. }
  31. }
  32. private static class NodeLevelAssigner {
  33. static void assignLevel(Node node) {
  34. foreach (ref child; node.children) {
  35. child.level = node.level + 1;
  36. assignLevel(child);
  37. }
  38. }
  39. }
  40. class Tree : Renderable {
  41. Node rootNode;
  42. this(Node rootNode) {
  43. this.dimension = Vector();
  44. this.rootNode = rootNode;
  45. NodeLevelAssigner.assignLevel(this.rootNode);
  46. }
  47. private void printTree(Node root, StackLayout column) {
  48. foreach (indx, child; root.children) {
  49. string labelText;
  50. for (int i = 0; i < child.level; ++i) {
  51. labelText ~= " ";
  52. if (i == (child.level - 1)) {
  53. if (indx == (root.children.length - 1)) {
  54. labelText ~= "└";
  55. } else {
  56. labelText ~= "├";
  57. }
  58. labelText ~= (" " ~ child.label);
  59. }
  60. }
  61. int len = cast(int)(labelText.length) - 4;
  62. ++dimension.y;
  63. if (len > this.dimension.x) {
  64. this.dimension.x = len;
  65. }
  66. column.add(new Label(Rect.empty(Vector(len, 1)), labelText.idup));
  67. printTree(child, column);
  68. }
  69. }
  70. override Cell[] render() {
  71. StackLayout column = new StackLayout(StackLayoutType.column);
  72. column.add(new Label(Rect.empty(Vector(cast(int)(rootNode.label.length), 1)), rootNode.label));
  73. printTree(rootNode, column);
  74. return column.render();
  75. }
  76. }