public void draw(ComponentDrawContext context) { CircuitState state = context.getCircuitState(); Graphics g = context.getGraphics(); GraphicsUtil.switchToWidth(g, WIDTH); g.setColor(state.getValue(e0).getColor()); g.drawLine(e0.getX(), e0.getY(), e1.getX(), e1.getY()); }
private void drawInstance(InstancePainter painter, boolean isGhost) { Graphics2D g = (Graphics2D) painter.getGraphics().create(); Location loc = painter.getLocation(); g.translate(loc.getX(), loc.getY()); Direction from = painter.getAttributeValue(StdAttr.FACING); int degrees = Direction.EAST.toDegrees() - from.toDegrees(); double radians = Math.toRadians((degrees + 360) % 360); g.rotate(radians); GraphicsUtil.switchToWidth(g, Wire.WIDTH); if (!isGhost && painter.getShowState()) { g.setColor(painter.getPort(0).getColor()); } g.drawLine(0, 0, 5, 0); GraphicsUtil.switchToWidth(g, 1); if (!isGhost && painter.shouldDrawColor()) { BitWidth width = painter.getAttributeValue(StdAttr.WIDTH); g.setColor(Value.repeat(Value.FALSE, width.getWidth()).getColor()); } g.drawLine(6, -8, 6, 8); g.drawLine(9, -5, 9, 5); g.drawLine(12, -2, 12, 2); g.dispose(); }
Location getInputOffset(GateAttributes attrs, int index) { int inputs = attrs.inputs; Direction facing = attrs.facing; int size = ((Integer) attrs.size.getValue()).intValue(); int axisLength = size + bonusWidth + (negateOutput ? 10 : 0); int negated = attrs.negated; int skipStart; int skipDist; int skipLowerEven = 10; if (inputs <= 3) { if (size < 40) { skipStart = -5; skipDist = 10; skipLowerEven = 10; } else if (size < 60 || inputs <= 2) { skipStart = -10; skipDist = 20; skipLowerEven = 20; } else { skipStart = -15; skipDist = 30; skipLowerEven = 30; } } else if (inputs == 4 && size >= 60) { skipStart = -5; skipDist = 20; skipLowerEven = 0; } else { skipStart = -5; skipDist = 10; skipLowerEven = 10; } int dy; if ((inputs & 1) == 1) { dy = skipStart * (inputs - 1) + skipDist * index; } else { dy = skipStart * inputs + skipDist * index; if (index >= inputs / 2) { dy += skipLowerEven; } } int dx = axisLength; int negatedBit = (negated >> index) & 1; if (negatedBit == 1) { dx += 10; } if (facing == Direction.NORTH) { return Location.create(dy, dx); } else if (facing == Direction.SOUTH) { return Location.create(dy, -dx); } else if (facing == Direction.WEST) { return Location.create(dx, dy); } else { return Location.create(-dx, dy); } }
@Override public void translate(int dx, int dy) { p0 = p0.translate(dx, dy); p1 = p1.translate(dx, dy); p2 = p2.translate(dx, dy); bounds = bounds.translate(dx, dy); }
private void paintBase(InstancePainter painter) { Graphics g = painter.getGraphics(); Direction facing = painter.getAttributeValue(StdAttr.FACING); Location loc = painter.getLocation(); int x = loc.getX(); int y = loc.getY(); g.translate(x, y); double rotate = 0.0; if (facing != null && facing != Direction.EAST && g instanceof Graphics2D) { rotate = -facing.toRadians(); ((Graphics2D) g).rotate(rotate); } Object shape = painter.getGateShape(); if (shape == AppPreferences.SHAPE_RECTANGULAR) { paintRectangularBase(g, painter); } else if (shape == AppPreferences.SHAPE_DIN40700) { int width = painter.getAttributeValue(ATTR_SIZE) == SIZE_NARROW ? 20 : 30; PainterDin.paintAnd(painter, width, 18, true); } else { PainterShaped.paintNot(painter); } if (rotate != 0.0) { ((Graphics2D) g).rotate(-rotate); } g.translate(-x, -y); }
@Override public int matchesHashCode() { int ret = p0.hashCode(); ret = ret * 31 * 31 + p1.hashCode(); ret = ret * 31 * 31 + p2.hashCode(); ret = ret * 31 + super.matchesHashCode(); return ret; }
public Bounds getOffsetBounds() { InstanceComponent c = comp; if (c == null) { return factory.getOffsetBounds(attrs); } else { Location loc = c.getLocation(); return c.getBounds().translate(-loc.getX(), -loc.getY()); } }
public ALU(Location loc, AttributeSet attrs) { super(loc, attrs, 5); setEnd(0, loc.translate(-30, -30), BITWIDTH_32, 1); setEnd(1, loc.translate(-30, 30), BITWIDTH_32, 1); setEnd(2, loc.translate(-10, 40), BITWIDTH_4, 1); setEnd(3, loc.translate(30, -20), BITWIDTH_1, 2); setEnd(4, loc.translate(30, 0), BITWIDTH_32, 2); setEnd(5, loc.translate(30, 20), BITWIDTH_1, 2); }
@Override public boolean contains(Location loc, AttributeSet attrs) { if (super.contains(loc, attrs)) { Direction facing = attrs.getValue(StdAttr.FACING); Location center = Location.create(0, 0).translate(facing, -20); return center.manhattanDistanceTo(loc) < 24; } else { return false; } }
private void computeLabel(Instance instance) { GateAttributes attrs = (GateAttributes) instance.getAttributeSet(); Direction facing = attrs.facing; int baseWidth = ((Integer) attrs.size.getValue()).intValue(); int axis = baseWidth / 2 + (negateOutput ? 10 : 0); int perp = 0; if (AppPreferences.GATE_SHAPE.get().equals(AppPreferences.SHAPE_RECTANGULAR)) { perp += 6; } Location loc = instance.getLocation(); int cx; int cy; if (facing == Direction.NORTH) { cx = loc.getX() + perp; cy = loc.getY() + axis; } else if (facing == Direction.SOUTH) { cx = loc.getX() - perp; cy = loc.getY() - axis; } else if (facing == Direction.WEST) { cx = loc.getX() + axis; cy = loc.getY() - perp; } else { cx = loc.getX() - axis; cy = loc.getY() + perp; } instance.setTextField( StdAttr.LABEL, StdAttr.LABEL_FONT, cx, cy, TextField.H_CENTER, TextField.V_CENTER); }
@Override public void mouseReleased(Canvas canvas, Graphics g, MouseEvent e) { Project proj = canvas.getProject(); if (state == MOVING) { setState(proj, IDLE); computeDxDy(proj, e, g); int dx = curDx; int dy = curDy; if (dx != 0 || dy != 0) { if (!proj.getLogisimFile().contains(canvas.getCircuit())) { canvas.setErrorMessage(Strings.getter("cannotModifyError")); } else if (proj.getSelection().hasConflictWhenMoved(dx, dy)) { canvas.setErrorMessage(Strings.getter("exclusiveError")); } else { boolean connect = shouldConnect(canvas, e.getModifiersEx()); drawConnections = false; ReplacementMap repl; if (connect) { MoveGesture gesture = moveGesture; if (gesture == null) { gesture = new MoveGesture( new MoveRequestHandler(canvas), canvas.getCircuit(), canvas.getSelection().getAnchoredComponents()); } canvas.setErrorMessage(new ComputingMessage(dx, dy), COLOR_COMPUTING); MoveResult result = gesture.forceRequest(dx, dy); clearCanvasMessage(canvas, dx, dy); repl = result.getReplacementMap(); } else { repl = null; } Selection sel = proj.getSelection(); proj.doAction(SelectionActions.translate(sel, dx, dy, repl)); } } moveGesture = null; proj.repaintCanvas(); } else if (state == RECT_SELECT) { Bounds bds = Bounds.create(start).add(start.getX() + curDx, start.getY() + curDy); Circuit circuit = canvas.getCircuit(); Selection sel = proj.getSelection(); Collection<Component> in_sel = sel.getComponentsWithin(bds, g); for (Component comp : circuit.getAllWithin(bds, g)) { if (!in_sel.contains(comp)) sel.add(comp); } Action act = SelectionActions.drop(sel, in_sel); if (act != null) { proj.doAction(act); } setState(proj, IDLE); proj.repaintCanvas(); } }
private void configurePorts(Instance instance) { Object size = instance.getAttributeValue(ATTR_SIZE); Direction facing = instance.getAttributeValue(StdAttr.FACING); int dx = size == SIZE_NARROW ? -20 : -30; Port[] ports = new Port[2]; ports[0] = new Port(0, 0, Port.OUTPUT, StdAttr.WIDTH); Location out = Location.create(0, 0).translate(facing, dx); ports[1] = new Port(out.getX(), out.getY(), Port.INPUT, StdAttr.WIDTH); instance.setPorts(ports); }
void computePorts(Instance instance) { GateAttributes attrs = (GateAttributes) instance.getAttributeSet(); int inputs = attrs.inputs; Port[] ports = new Port[inputs + 1]; ports[0] = new Port(0, 0, Port.OUTPUT, StdAttr.WIDTH); for (int i = 0; i < inputs; i++) { Location offs = getInputOffset(attrs, i); ports[i + 1] = new Port(offs.getX(), offs.getY(), Port.INPUT, StdAttr.WIDTH); } instance.setPorts(ports); }
static Location snapTo4Cardinals(Location from, int mx, int my) { int px = from.getX(); int py = from.getY(); if (mx != px && my != py) { if (Math.abs(my - py) < Math.abs(mx - px)) { return Location.create(mx, py); } else { return Location.create(px, my); } } return Location.create(mx, my); // should never happen }
@Override public void paintInstance(InstancePainter painter) { Location loc = painter.getLocation(); int x = loc.getX(); int y = loc.getY(); Graphics g = painter.getGraphics(); g.translate(x, y); Value pull = getPullValue(painter.getAttributeSet()); Value actual = painter.getPort(0); paintBase(painter, pull, pull.getColor(), actual.getColor()); g.translate(-x, -y); painter.drawPorts(); }
@Override public void mouseDragged(Canvas canvas, Graphics g, MouseEvent e) { if (state == MOVING) { Project proj = canvas.getProject(); computeDxDy(proj, e, g); handleMoveDrag(canvas, curDx, curDy, e.getModifiersEx()); } else if (state == RECT_SELECT) { Project proj = canvas.getProject(); curDx = e.getX() - start.getX(); curDy = e.getY() - start.getY(); proj.repaintCanvas(); } }
@Override public void paste() { ClipboardContents clip = Clipboard.get(); Collection<CanvasObject> contents = clip.getElements(); List<CanvasObject> add = new ArrayList<CanvasObject>(contents.size()); for (CanvasObject o : contents) { add.add(o.clone()); } if (add.isEmpty()) return; // find how far we have to translate shapes so that at least one of the // pasted shapes doesn't match what's already in the model Collection<CanvasObject> raw = canvas.getModel().getObjectsFromBottom(); MatchingSet<CanvasObject> cur = new MatchingSet<CanvasObject>(raw); int dx = 0; while (true) { // if any shapes in "add" aren't in canvas, we are done boolean allMatch = true; for (CanvasObject o : add) { if (!cur.contains(o)) { allMatch = false; break; } } if (!allMatch) break; // otherwise translate everything by 10 pixels and repeat test for (CanvasObject o : add) { o.translate(10, 10); } dx += 10; } Location anchorLocation = clip.getAnchorLocation(); if (anchorLocation != null && dx != 0) { anchorLocation = anchorLocation.translate(dx, dx); } canvas .getProject() .doAction( new SelectionAction( canvas, Strings.getter("pasteClipboardAction"), null, add, add, anchorLocation, clip.getAnchorFacing())); }
public static AbstractCanvasObject createShape(Element elt, Map<Location, Instance> pins) { String name = elt.getTagName(); if (name.equals("circ-anchor") || name.equals("circ-origin")) { Location loc = getLocation(elt); AbstractCanvasObject ret = new AppearanceAnchor(loc); if (elt.hasAttribute("facing")) { Direction facing = Direction.parse(elt.getAttribute("facing")); ret.setValue(AppearanceAnchor.FACING, facing); } return ret; } else if (name.equals("circ-port")) { Location loc = getLocation(elt); String[] pinStr = elt.getAttribute("pin").split(","); Location pinLoc = Location.create(Integer.parseInt(pinStr[0].trim()), Integer.parseInt(pinStr[1].trim())); Instance pin = pins.get(pinLoc); if (pin == null) { return null; } else { return new AppearancePort(loc, pin); } } else { return SvgReader.createShape(elt); } }
@Override public void mousePressed(Canvas canvas, Graphics g, MouseEvent e) { Project proj = canvas.getProject(); Selection sel = proj.getSelection(); Circuit circuit = canvas.getCircuit(); start = Location.create(e.getX(), e.getY()); curDx = 0; curDy = 0; moveGesture = null; // if the user clicks into the selection, // selection is being modified Collection<Component> in_sel = sel.getComponentsContaining(start, g); if (!in_sel.isEmpty()) { if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) { setState(proj, MOVING); proj.repaintCanvas(); return; } else { Action act = SelectionActions.drop(sel, in_sel); if (act != null) { proj.doAction(act); } } } // if the user clicks into a component outside selection, user // wants to add/reset selection Collection<Component> clicked = circuit.getAllContaining(start, g); if (!clicked.isEmpty()) { if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) { if (sel.getComponentsContaining(start).isEmpty()) { Action act = SelectionActions.dropAll(sel); if (act != null) { proj.doAction(act); } } } for (Component comp : clicked) { if (!in_sel.contains(comp)) { sel.add(comp); } } setState(proj, MOVING); proj.repaintCanvas(); return; } // The user clicked on the background. This is a rectangular // selection (maybe with the shift key down). if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) { Action act = SelectionActions.dropAll(sel); if (act != null) { proj.doAction(act); } } setState(proj, RECT_SELECT); proj.repaintCanvas(); }
@Override public void mousePressed(Canvas canvas, MouseEvent e) { int x = e.getX(); int y = e.getY(); int mods = e.getModifiersEx(); if ((mods & InputEvent.CTRL_DOWN_MASK) != 0) { x = canvas.snapX(x); y = canvas.snapY(y); } Location loc = Location.create(x, y); mouseStart = loc; mouseEnd = loc; lastMouseX = loc.getX(); lastMouseY = loc.getY(); active = canvas.getModel() != null; repaintArea(canvas); }
private static Location getLocation(Element elt) { double x = Double.parseDouble(elt.getAttribute("x")); double y = Double.parseDouble(elt.getAttribute("y")); double w = Double.parseDouble(elt.getAttribute("width")); double h = Double.parseDouble(elt.getAttribute("height")); int px = (int) Math.round(x + w / 2); int py = (int) Math.round(y + h / 2); return Location.create(px, py); }
public boolean contains(Location q) { int qx = q.getX(); int qy = q.getY(); if (is_x_equal) { int wx = e0.getX(); return qx >= wx - 2 && qx <= wx + 2 && e0.getY() <= qy && qy <= e1.getY(); } else { int wy = e0.getY(); return qy >= wy - 2 && qy <= wy + 2 && e0.getX() <= qx && qx <= e1.getX(); } }
private Handle[] getHandleArray(HandleGesture gesture) { if (gesture == null) { return new Handle[] { new Handle(this, p0), new Handle(this, p1), new Handle(this, p2) }; } else { Handle g = gesture.getHandle(); int gx = g.getX() + gesture.getDeltaX(); int gy = g.getY() + gesture.getDeltaY(); Handle[] ret = { new Handle(this, p0), new Handle(this, p1), new Handle(this, p2) }; if (g.isAt(p0)) { if (gesture.isShiftDown()) { Location p = LineUtil.snapTo8Cardinals(p2, gx, gy); ret[0] = new Handle(this, p); } else { ret[0] = new Handle(this, gx, gy); } } else if (g.isAt(p2)) { if (gesture.isShiftDown()) { Location p = LineUtil.snapTo8Cardinals(p0, gx, gy); ret[2] = new Handle(this, p); } else { ret[2] = new Handle(this, gx, gy); } } else if (g.isAt(p1)) { if (gesture.isShiftDown()) { double x0 = p0.getX(); double y0 = p0.getY(); double x1 = p2.getX(); double y1 = p2.getY(); double midx = (x0 + x1) / 2; double midy = (y0 + y1) / 2; double dx = x1 - x0; double dy = y1 - y0; double[] p = LineUtil.nearestPointInfinite(gx, gy, midx, midy, midx - dy, midy + dx); gx = (int) Math.round(p[0]); gy = (int) Math.round(p[1]); } if (gesture.isAltDown()) { double[] e0 = { p0.getX(), p0.getY() }; double[] e1 = { p2.getX(), p2.getY() }; double[] mid = { gx, gy }; double[] ct = CurveUtil.interpolate(e0, e1, mid); gx = (int) Math.round(ct[0]); gy = (int) Math.round(ct[1]); } ret[1] = new Handle(this, gx, gy); } return ret; } }
@Override public void mouseReleased(Canvas canvas, MouseEvent e) { if (active) { updateMouse(canvas, e.getX(), e.getY(), e.getModifiersEx()); Location start = mouseStart; Location end = mouseEnd; CanvasObject add = null; if (!start.equals(end)) { active = false; CanvasModel model = canvas.getModel(); Location[] ends = {start, end}; List<Location> locs = UnmodifiableList.create(ends); add = attrs.applyTo(new Poly(false, locs)); add.setValue(DrawAttr.PAINT_TYPE, DrawAttr.PAINT_STROKE); canvas.doAction(new ModelAddAction(model, add)); repaintArea(canvas); } canvas.toolGestureComplete(this, add); } }
private void computeDxDy(Project proj, MouseEvent e, Graphics g) { Bounds bds = proj.getSelection().getBounds(g); int dx; int dy; if (bds == Bounds.EMPTY_BOUNDS) { dx = e.getX() - start.getX(); dy = e.getY() - start.getY(); } else { dx = Math.max(e.getX() - start.getX(), -bds.getX()); dy = Math.max(e.getY() - start.getY(), -bds.getY()); } Selection sel = proj.getSelection(); if (sel.shouldSnap()) { dx = Canvas.snapXToGrid(dx); dy = Canvas.snapYToGrid(dy); } curDx = dx; curDy = dy; }
private static List<Location> parsePoints(String points) { Pattern patt = Pattern.compile("[ ,\n\r\t]+"); String[] toks = patt.split(points); Location[] ret = new Location[toks.length / 2]; for (int i = 0; i < ret.length; i++) { int x = Integer.parseInt(toks[2 * i]); int y = Integer.parseInt(toks[2 * i + 1]); ret[i] = Location.create(x, y); } return UnmodifiableList.create(ret); }
public EndData toEnd(Location loc, AttributeSet attrs) { Location pt = loc.translate(dx, dy); if (widthFixed != null) { return new EndData(pt, widthFixed, type, exclude); } else { Object val = attrs.getValue(widthAttr); if (!(val instanceof BitWidth)) { throw new IllegalArgumentException("Width attribute not set"); } return new EndData(pt, (BitWidth) val, type, exclude); } }
private void updateMouse(Canvas canvas, int mx, int my, int mods) { if (active) { boolean shift = (mods & MouseEvent.SHIFT_DOWN_MASK) != 0; Location newEnd; if (shift) { newEnd = LineUtil.snapTo8Cardinals(mouseStart, mx, my); } else { newEnd = Location.create(mx, my); } if ((mods & InputEvent.CTRL_DOWN_MASK) != 0) { int x = newEnd.getX(); int y = newEnd.getY(); x = canvas.snapX(x); y = canvas.snapY(y); newEnd = Location.create(x, y); } if (!newEnd.equals(mouseEnd)) { mouseEnd = newEnd; repaintArea(canvas); } } lastMouseX = mx; lastMouseY = my; }
static void configureLabel(Instance instance, boolean isRectangular, Location control) { Object facing = instance.getAttributeValue(StdAttr.FACING); Bounds bds = instance.getBounds(); int x; int y; int halign; if (facing == Direction.NORTH || facing == Direction.SOUTH) { x = bds.getX() + bds.getWidth() / 2 + 2; y = bds.getY() - 2; halign = TextField.H_LEFT; } else { // west or east y = isRectangular ? bds.getY() - 2 : bds.getY(); if (control != null && control.getY() == bds.getY()) { // the control line will get in the way x = control.getX() + 2; halign = TextField.H_LEFT; } else { x = bds.getX() + bds.getWidth() / 2; halign = TextField.H_CENTER; } } instance.setTextField(StdAttr.LABEL, StdAttr.LABEL_FONT, x, y, halign, TextField.V_BASELINE); }
@Override public void draw(Canvas canvas, Graphics g) { if (active) { Location start = mouseStart; Location end = mouseEnd; g.setColor(Color.GRAY); g.drawLine(start.getX(), start.getY(), end.getX(), end.getY()); } }