Adds: Hold down T to connect elements with other elements. The elements added are TopologyBox, which are subclasses of Box that have a default drawer that draws arcs between endpoints. This is more proof of concept that anything else. The interpretation of this "topology" is completely up to the
| 27 | * concept that anything else. The interpretation of this "topology" is completely up to the code in the boxes themselves. |
| 28 | */ |
| 29 | public class Topology extends Box implements Mouse.OnMouseDown { |
| 30 | |
| 31 | static public final Dict.Prop<FunctionOfBoxValued<BoxChildHelper>> outward = new Dict.Prop<FunctionOfBoxValued<BoxChildHelper>>("outward").doc("a collection of boxes that are the outward connections to this box") |
| 32 | .toCanon() |
| 33 | .type(); |
| 34 | static public final Dict.Prop<FunctionOfBoxValued<BoxChildHelper>> inward = new Dict.Prop<FunctionOfBoxValued<BoxChildHelper>>("inward").doc("a collection of boxes that are the inward connections to this box") |
| 35 | .toCanon() |
| 36 | .type(); |
| 37 | |
| 38 | private final Box root; |
| 39 | boolean on = false; |
| 40 | |
| 41 | public Topology(Box root) { |
| 42 | this.root = root; |
| 43 | this.properties.put(Planes.plane, "__always__"); |
| 44 | this.properties.putToMap(Mouse.onMouseDown, "__topology__", this); |
| 45 | |
| 46 | root.properties.put(outward, (box) -> { |
| 47 | return new BoxChildHelper(box.children() |
| 48 | .stream() |
| 49 | .filter(x -> x.properties.has(TopologyBox.head)) |
| 50 | .filter(x -> x.properties.get(TopologyBox.head) |
| 51 | .get(root) == box) |
| 52 | .map(x -> x.properties.get(TopologyBox.tail) |
| 53 | .get(root)) |
| 54 | .collect(Collectors.toCollection(() -> new LinkedHashSet<>()))); |
| 55 | }); |
| 56 | root.properties.put(inward, (box) -> { |
| 57 | return new BoxChildHelper(box.children() |
| 58 | .stream() |
| 59 | .filter(x -> x.properties.has(TopologyBox.tail)) |
| 60 | .filter(x -> x.properties.get(TopologyBox.tail) |
| 61 | .get(root) == box) |
| 62 | .map(x -> x.properties.get(TopologyBox.head) |
| 63 | .get(root)) |
| 64 | .collect(Collectors.toCollection(() -> new LinkedHashSet<>()))); |
| 65 | }); |
| 66 | } |
| 67 | |
| 68 | @Override |
| 69 | public Mouse.Dragger onMouseDown(Window.Event<Window.MouseState> e, int button) { |
| 70 | if (button == 0) return button0(e); |
| 71 | return null; |
| 72 | } |
| 73 | |
| 74 | protected Mouse.Dragger button0(Window.Event<Window.MouseState> e) { |
| 75 | if (!e.after.keyboardState.keysDown.contains(GLFW_KEY_T)) return null; |
| 76 | |
| 77 | Optional<Drawing> drawing = this.find(Drawing.drawing, both()) |
| 78 | .findFirst(); |
| 79 | Vec2 point = new Vec2(e.after.mx, e.after.my); |
| 80 | |
| 81 | Optional<Box> hit = breadthFirst(both()).filter(b -> frame(b) != null) |
| 82 | .filter(x -> !x.properties.isTrue(Box.hidden, false)) |
| 83 | .filter(b -> frame(b).intersects(point)) |
| 84 | .sorted((a, b) -> Float.compare(order(frame(a)), order(frame(b)))) |
| 85 | .findFirst(); |
| 86 |