A Box with a custom drawer for holding onto and drawning a connection between two other boxes. Automatically deletes itself should either of its two ends disappears.
| 27 | * Automatically deletes itself should either of its two ends disappears. |
| 28 | */ |
| 29 | public class TopologyBox extends Box |
| 30 | implements IO.Loaded // the drawer is initialized after all the properties are loaded |
| 31 | { |
| 32 | |
| 33 | static public final Dict.Prop<BoxRef> head = new Dict.Prop<>("head").type().toCanon().doc("the head of this topology arrow box"); |
| 34 | static public final Dict.Prop<BoxRef> tail = new Dict.Prop<>("tail").type().toCanon().doc("the tail of this topology arrow box"); |
| 35 | |
| 36 | static { |
| 37 | // these properties need to be saved in our document |
| 38 | IO.persist(head); |
| 39 | IO.persist(tail); |
| 40 | } |
| 41 | |
| 42 | public TopologyBox(Box head, Box tail) { |
| 43 | this.properties.put(TopologyBox.head, new BoxRef(head)); |
| 44 | this.properties.put(TopologyBox.tail, new BoxRef(tail)); |
| 45 | |
| 46 | loaded(); |
| 47 | } |
| 48 | |
| 49 | /** |
| 50 | * custom constructor, call init after you are done |
| 51 | */ |
| 52 | public TopologyBox() { |
| 53 | } |
| 54 | |
| 55 | public void loaded() { |
| 56 | this.properties.putToMap(Boxes.insideRunLoop, "main.__checkfordeletion__", this::checkForDeletion); |
| 57 | this.properties.putToMap(Boxes.insideRunLoop, "main.__updateframe__", this::updateFrameToMiddle); |
| 58 | this.properties.computeIfAbsent(frameDrawing, this::defaultdrawsLines); |
| 59 | this.properties.put(frame, head().properties.get(frame).union(tail().properties.get(frame))); |
| 60 | this.properties.put(FrameManipulation.lockHeight, true); // the dimensions of this box cannot be changed |
| 61 | this.properties.put(FrameManipulation.lockWidth, true); |
| 62 | this.properties.put(FrameManipulation.lockX, true); // nor can its position |
| 63 | this.properties.put(FrameManipulation.lockY, true); |
| 64 | |
| 65 | this.properties.put(Box.name, head().properties.get(Box.name) + "->" + tail().properties.get(Box.name)); |
| 66 | this.properties.put(DragToCopy._ownedByParent, true); |
| 67 | } |
| 68 | |
| 69 | |
| 70 | protected Map<String, Function<Box, FLine>> defaultdrawsLines(Dict.Prop<Map<String, Function<Box, FLine>>> k) { |
| 71 | Map<String, Function<Box, FLine>> r = new LinkedHashMap<>(); |
| 72 | |
| 73 | r.put("__outline__", new Cached<Box, Object, FLine>((box, previously) -> { |
| 74 | Rect rect = box.properties.get(frame); |
| 75 | if (rect == null) return null; |
| 76 | |
| 77 | FLine f = arc(((TopologyBox) box).head().properties.get(frame), ((TopologyBox) box).tail().properties.get(frame)); |
| 78 | |
| 79 | f = thickenArc(f, ((TopologyBox) box).head().properties.get(frame), ((TopologyBox) box).tail().properties.get(frame)); |
| 80 | |
| 81 | boolean selected = box.properties.isTrue(Mouse.isSelected, false); |
| 82 | |
| 83 | f.attributes.put(fillColor, selected ? new Vec4(1, 1, 1, -1f) : new Vec4(1, 1, 1, 0.85f)); |
| 84 | f.attributes.put(strokeColor, selected ? new Vec4(1, 1, 1, 0.25f) : new Vec4(1, 1, 1, 0.15f)); |
| 85 | f.attributes.put(thicken, new BasicStroke(selected ? 3 : 0.5f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER)); |
| 86 |