The final restructured version for automatic build using maven tycho
[Mograsim.git] / plugins / net.mograsim.logic.model.editor / src / net / mograsim / logic / model / editor / Selection.java
diff --git a/plugins/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/Selection.java b/plugins/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/Selection.java
new file mode 100644 (file)
index 0000000..bc225eb
--- /dev/null
@@ -0,0 +1,132 @@
+package net.mograsim.logic.model.editor;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.DoubleBinaryOperator;
+
+import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
+import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
+import net.mograsim.logic.model.editor.handles.Handle;
+
+public class Selection implements Iterable<Handle>
+{
+       private Set<Handle> selection = new HashSet<>();
+
+       public Map<Handle, Point> calculateOffsets()
+       {
+               Map<Handle, Point> offsets = new HashMap<>();
+               Point ref = getTopLeft();
+               selection.forEach(h -> offsets.put(h, new Point(h.getPosX() - ref.x, h.getPosY() - ref.y)));
+               return offsets;
+       }
+
+       public Rectangle getBounds()
+       {
+               Point pos1 = getTopLeft();
+               Point pos2 = getBottomRight();
+               return new Rectangle(pos1.x, pos1.y, pos2.x - pos1.x, pos2.y - pos1.y);
+       }
+
+       public double getWidth()
+       {// TODO: Compute this more efficiently
+               return getTopRight().x - getTopLeft().x;
+       }
+
+       public double getHeight()
+       {
+               return getBottomLeft().y - getTopLeft().y;
+       }
+
+       public Point getTopLeft()
+       {
+               return getCorner(Double.MAX_VALUE, Double::min, r -> 0, Double.MAX_VALUE, Double::min, r -> 0);
+       }
+
+       public Point getTopRight()
+       {
+               return getCorner(-Double.MAX_VALUE, Double::max, r -> r.width, Double.MAX_VALUE, Double::min, r -> 0);
+       }
+
+       public Point getBottomLeft()
+       {
+               return getCorner(Double.MAX_VALUE, Double::min, r -> 0, -Double.MAX_VALUE, Double::max, r -> r.height);
+       }
+
+       public Point getBottomRight()
+       {
+               return getCorner(-Double.MAX_VALUE, Double::max, r -> r.width, -Double.MAX_VALUE, Double::max, r -> r.height);
+       }
+
+       public Point getCorner(double xIdentity, DoubleBinaryOperator xOp, Offset xOffset, double yIdentity, DoubleBinaryOperator yOp,
+                       Offset yOffset)
+       {
+               double x = xIdentity, y = yIdentity;
+               for (Handle c : selection)
+               {
+                       Rectangle bounds = c.getBounds();
+                       x = xOp.applyAsDouble(x, bounds.x + xOffset.computeOffset(bounds));
+                       y = yOp.applyAsDouble(y, bounds.y + yOffset.computeOffset(bounds));
+               }
+               return new Point(x, y);
+       }
+
+       private static interface Offset
+       {
+               public double computeOffset(Rectangle bounds);
+       }
+
+       public void add(Handle h)
+       {
+               selection.add(h);
+               h.onSelect();
+       }
+
+       public void remove(Handle h)
+       {
+               selection.remove(h);
+               h.onDeselect();
+       }
+
+       public void clear()
+       {
+               selection.forEach(h -> h.onDeselect());
+               selection.clear();
+       }
+
+       public int size()
+       {
+               return selection.size();
+       }
+
+       public boolean contains(Handle h)
+       {
+               return selection.contains(h);
+       }
+
+       public void addAll(Collection<Handle> handles)
+       {
+               handles.forEach(h -> h.onSelect());
+               selection.addAll(handles);
+       }
+
+       @Override
+       public Iterator<Handle> iterator()
+       {
+               return selection.iterator();
+       }
+
+       @Override
+       public String toString()
+       {
+               return selection.toString();
+       }
+
+       public boolean isEmpty()
+       {
+               return selection.isEmpty();
+       }
+}