X-Git-Url: https://mograsim.net/gitweb/?a=blobdiff_plain;f=plugins%2Fnet.mograsim.logic.model.editor%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fmodel%2Feditor%2FSelection.java;fp=plugins%2Fnet.mograsim.logic.model.editor%2Fsrc%2Fnet%2Fmograsim%2Flogic%2Fmodel%2Feditor%2FSelection.java;h=bc225eb7073221639c1f8117de4593f64044850e;hb=7d05144c25daa53e60fc9ed9fd503546a86567f8;hp=0000000000000000000000000000000000000000;hpb=8bed58cd47f4e53a0a83e066d38864aa6875502f;p=Mograsim.git 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 index 00000000..bc225eb7 --- /dev/null +++ b/plugins/net.mograsim.logic.model.editor/src/net/mograsim/logic/model/editor/Selection.java @@ -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 +{ + private Set selection = new HashSet<>(); + + public Map calculateOffsets() + { + Map 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 handles) + { + handles.forEach(h -> h.onSelect()); + selection.addAll(handles); + } + + @Override + public Iterator iterator() + { + return selection.iterator(); + } + + @Override + public String toString() + { + return selection.toString(); + } + + public boolean isEmpty() + { + return selection.isEmpty(); + } +}