1 package net.mograsim.logic.model.editor;
3 import java.util.Collection;
4 import java.util.HashMap;
5 import java.util.HashSet;
6 import java.util.Iterator;
9 import java.util.function.DoubleBinaryOperator;
11 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
12 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
13 import net.mograsim.logic.model.editor.handles.Handle;
15 public class Selection implements Iterable<Handle>
17 private Set<Handle> selection = new HashSet<>();
19 public Map<Handle, Point> calculateOffsets()
21 Map<Handle, Point> offsets = new HashMap<>();
22 Point ref = getTopLeft();
23 selection.forEach(h -> offsets.put(h, new Point(h.getPosX() - ref.x, h.getPosY() - ref.y)));
27 public Rectangle getBounds()
29 Point pos1 = getTopLeft();
30 Point pos2 = getBottomRight();
31 return new Rectangle(pos1.x, pos1.y, pos2.x - pos1.x, pos2.y - pos1.y);
34 public double getWidth()
35 {// TODO: Compute this more efficiently
36 return getTopRight().x - getTopLeft().x;
39 public double getHeight()
41 return getBottomLeft().y - getTopLeft().y;
44 public Point getTopLeft()
46 return getCorner(Double.MAX_VALUE, Double::min, r -> 0, Double.MAX_VALUE, Double::min, r -> 0);
49 public Point getTopRight()
51 return getCorner(-Double.MAX_VALUE, Double::max, r -> r.width, Double.MAX_VALUE, Double::min, r -> 0);
54 public Point getBottomLeft()
56 return getCorner(Double.MAX_VALUE, Double::min, r -> 0, -Double.MAX_VALUE, Double::max, r -> r.height);
59 public Point getBottomRight()
61 return getCorner(-Double.MAX_VALUE, Double::max, r -> r.width, -Double.MAX_VALUE, Double::max, r -> r.height);
64 public Point getCorner(double xIdentity, DoubleBinaryOperator xOp, Offset xOffset, double yIdentity, DoubleBinaryOperator yOp,
67 double x = xIdentity, y = yIdentity;
68 for (Handle c : selection)
70 Rectangle bounds = c.getBounds();
71 x = xOp.applyAsDouble(x, bounds.x + xOffset.computeOffset(bounds));
72 y = yOp.applyAsDouble(y, bounds.y + yOffset.computeOffset(bounds));
74 return new Point(x, y);
77 private static interface Offset
79 public double computeOffset(Rectangle bounds);
82 public void add(Handle h)
88 public void remove(Handle h)
96 selection.forEach(h -> h.onDeselect());
102 return selection.size();
105 public boolean contains(Handle h)
107 return selection.contains(h);
110 public void addAll(Collection<Handle> handles)
112 handles.forEach(h -> h.onSelect());
113 selection.addAll(handles);
117 public Iterator<Handle> iterator()
119 return selection.iterator();
123 public String toString()
125 return selection.toString();
128 public boolean isEmpty()
130 return selection.isEmpty();