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 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 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()); } }
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; } }
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(); }
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); }
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; }
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()); } }
@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 Wire(Location e0, Location e1) { this.is_x_equal = e0.getX() == e1.getX(); if (is_x_equal) { if (e0.getY() > e1.getY()) { this.e0 = e1; this.e1 = e0; } else { this.e0 = e0; this.e1 = e1; } } else { if (e0.getX() > e1.getX()) { this.e0 = e1; this.e1 = e0; } else { this.e0 = e0; this.e1 = e1; } } }
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 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); }
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 }
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); }
@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 boolean contains(Location loc, AttributeSet attrsBase) { GateAttributes attrs = (GateAttributes) attrsBase; if (super.contains(loc, attrs)) { if (attrs.negated == 0) { return true; } else { Direction facing = attrs.facing; Bounds bds = getOffsetBounds(attrsBase); int delt; if (facing == Direction.NORTH) { delt = loc.getY() - (bds.getY() + bds.getHeight()); } else if (facing == Direction.SOUTH) { delt = loc.getY() - bds.getY(); } else if (facing == Direction.WEST) { delt = loc.getX() - (bds.getX() + bds.getHeight()); } else { delt = loc.getX() - bds.getX(); } if (Math.abs(delt) > 5) { return true; } else { int inputs = attrs.inputs; for (int i = 1; i <= inputs; i++) { Location offs = getInputOffset(attrs, i); if (loc.manhattanDistanceTo(offs) <= 5) { return true; } } return false; } } } else { return false; } }
@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); }
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 boolean contains(Location loc, boolean assumeFilled) { Object type = getPaintType(); if (assumeFilled && type == DrawAttr.PAINT_STROKE) { type = DrawAttr.PAINT_STROKE_FILL; } if (type != DrawAttr.PAINT_FILL) { int stroke = getStrokeWidth(); double[] q = toArray(loc); double[] p0 = toArray(this.p0); double[] p1 = toArray(this.p1); double[] p2 = toArray(this.p2); double[] p = CurveUtil.findNearestPoint(q, p0, p1, p2); if (p == null) { return false; } int thr; if (type == DrawAttr.PAINT_STROKE) { thr = Math.max(Line.ON_LINE_THRESH, stroke / 2); } else { thr = stroke / 2; } if (LineUtil.distanceSquared(p[0], p[1], q[0], q[1]) < thr * thr) { return true; } } if (type != DrawAttr.PAINT_STROKE) { QuadCurve2D curve = getCurve(null); if (curve.contains(loc.getX(), loc.getY())) { return true; } } return false; }
private static double[] toArray(Location loc) { return new double[] { loc.getX(), loc.getY() }; }
public Handle(CanvasObject object, Location loc) { this(object, loc.getX(), loc.getY()); }
public boolean isAt(Location loc) { return x == loc.getX() && y == loc.getY(); }
public int getLength() { return (e1.getY() - e0.getY()) + (e1.getX() - e0.getX()); }
private void paintBase(InstancePainter painter) { GateAttributes attrs = (GateAttributes) painter.getAttributeSet(); Direction facing = attrs.facing; int inputs = attrs.inputs; int negated = attrs.negated; Object shape = painter.getGateShape(); Location loc = painter.getLocation(); Bounds bds = painter.getOffsetBounds(); int width = bds.getWidth(); int height = bds.getHeight(); if (facing == Direction.NORTH || facing == Direction.SOUTH) { int t = width; width = height; height = t; } if (negated != 0) { width -= 10; } Graphics g = painter.getGraphics(); Color baseColor = g.getColor(); if (shape == AppPreferences.SHAPE_SHAPED && paintInputLines) { PainterShaped.paintInputLines(painter, this); } else if (negated != 0) { for (int i = 0; i < inputs; i++) { int negatedBit = (negated >> i) & 1; if (negatedBit == 1) { Location in = getInputOffset(attrs, i); Location cen = in.translate(facing, 5); painter.drawDongle(loc.getX() + cen.getX(), loc.getY() + cen.getY()); } } } g.setColor(baseColor); g.translate(loc.getX(), loc.getY()); double rotate = 0.0; if (facing != Direction.EAST && g instanceof Graphics2D) { rotate = -facing.toRadians(); Graphics2D g2 = (Graphics2D) g; g2.rotate(rotate); } if (shape == AppPreferences.SHAPE_RECTANGULAR) { paintRectangular(painter, width, height); } else if (shape == AppPreferences.SHAPE_DIN40700) { paintDinShape(painter, width, height, inputs); // SHAPE_SHAPED } else { if (negateOutput) { g.translate(-10, 0); paintShape(painter, width - 10, height); painter.drawDongle(5, 0); g.translate(10, 0); } else { paintShape(painter, width, height); } } if (rotate != 0.0) { ((Graphics2D) g).rotate(-rotate); } g.translate(-loc.getX(), -loc.getY()); painter.drawLabel(); }
@Override public void mousePressed(Canvas canvas, Graphics g, MouseEvent e) { Project proj = canvas.getProject(); Circuit circ = canvas.getCircuit(); if (!proj.getLogisimFile().contains(circ)) { if (caret != null) caret.cancelEditing(); canvas.setErrorMessage(Strings.getter("cannotModifyError")); return; } // Maybe user is clicking within the current caret. if (caret != null) { if (caret.getBounds(g).contains(e.getX(), e.getY())) { // Yes caret.mousePressed(e); proj.repaintCanvas(); return; } else { // No. End the current caret. caret.stopEditing(); } } // caret will be null at this point // Otherwise search for a new caret. int x = e.getX(); int y = e.getY(); Location loc = Location.create(x, y); ComponentUserEvent event = new ComponentUserEvent(canvas, x, y); // First search in selection. for (Component comp : proj.getSelection().getComponentsContaining(loc, g)) { TextEditable editable = (TextEditable) comp.getFeature(TextEditable.class); if (editable != null) { caret = editable.getTextCaret(event); if (caret != null) { proj.getFrame().viewComponentAttributes(circ, comp); caretComponent = comp; caretCreatingText = false; break; } } } // Then search in circuit if (caret == null) { for (Component comp : circ.getAllContaining(loc, g)) { TextEditable editable = (TextEditable) comp.getFeature(TextEditable.class); if (editable != null) { caret = editable.getTextCaret(event); if (caret != null) { proj.getFrame().viewComponentAttributes(circ, comp); caretComponent = comp; caretCreatingText = false; break; } } } } // if nothing found, create a new label if (caret == null) { if (loc.getX() < 0 || loc.getY() < 0) return; AttributeSet copy = (AttributeSet) attrs.clone(); caretComponent = Text.FACTORY.createComponent(loc, copy); caretCreatingText = true; TextEditable editable = (TextEditable) caretComponent.getFeature(TextEditable.class); if (editable != null) { caret = editable.getTextCaret(event); proj.getFrame().viewComponentAttributes(circ, caretComponent); } } if (caret != null) { caretCanvas = canvas; caretCircuit = canvas.getCircuit(); caret.addCaretListener(listener); caretCircuit.addCircuitListener(listener); } proj.repaintCanvas(); }
private boolean overlaps(Location q0, Location q1, boolean includeEnds) { if (is_x_equal) { int x0 = q0.getX(); if (x0 != q1.getX() || x0 != e0.getX()) return false; if (includeEnds) { return e1.getY() >= q0.getY() && e0.getY() <= q1.getY(); } else { return e1.getY() > q0.getY() && e0.getY() < q1.getY(); } } else { int y0 = q0.getY(); if (y0 != q1.getY() || y0 != e0.getY()) return false; if (includeEnds) { return e1.getX() >= q0.getX() && e0.getX() <= q1.getX(); } else { return e1.getX() > q0.getX() && e0.getX() < q1.getX(); } } }
public QuadCurve2D getCurve2D() { return new QuadCurve2D.Double(p0.getX(), p0.getY(), p1.getX(), p1.getY(), p2.getX(), p2.getY()); }
@Override public void draw(Canvas canvas, ComponentDrawContext context) { Project proj = canvas.getProject(); int dx = curDx; int dy = curDy; if (state == MOVING) { proj.getSelection().drawGhostsShifted(context, dx, dy); MoveGesture gesture = moveGesture; if (gesture != null && drawConnections && (dx != 0 || dy != 0)) { MoveResult result = gesture.findResult(dx, dy); if (result != null) { Collection<Wire> wiresToAdd = result.getWiresToAdd(); Graphics g = context.getGraphics(); GraphicsUtil.switchToWidth(g, 3); g.setColor(Color.GRAY); for (Wire w : wiresToAdd) { Location loc0 = w.getEnd0(); Location loc1 = w.getEnd1(); g.drawLine(loc0.getX(), loc0.getY(), loc1.getX(), loc1.getY()); } GraphicsUtil.switchToWidth(g, 1); g.setColor(COLOR_UNMATCHED); for (Location conn : result.getUnconnectedLocations()) { int connX = conn.getX(); int connY = conn.getY(); g.fillOval(connX - 3, connY - 3, 6, 6); g.fillOval(connX + dx - 3, connY + dy - 3, 6, 6); } } } } else if (state == RECT_SELECT) { int left = start.getX(); int right = left + dx; if (left > right) { int i = left; left = right; right = i; } int top = start.getY(); int bot = top + dy; if (top > bot) { int i = top; top = bot; bot = i; } Graphics gBase = context.getGraphics(); int w = right - left - 1; int h = bot - top - 1; if (w > 2 && h > 2) { gBase.setColor(BACKGROUND_RECT_SELECT); gBase.fillRect(left + 1, top + 1, w - 1, h - 1); } Circuit circ = canvas.getCircuit(); Bounds bds = Bounds.create(left, top, right - left, bot - top); for (Component c : circ.getAllWithin(bds)) { Location cloc = c.getLocation(); Graphics gDup = gBase.create(); context.setGraphics(gDup); c.getFactory() .drawGhost(context, COLOR_RECT_SELECT, cloc.getX(), cloc.getY(), c.getAttributeSet()); gDup.dispose(); } gBase.setColor(COLOR_RECT_SELECT); GraphicsUtil.switchToWidth(gBase, 2); if (w < 0) w = 0; if (h < 0) h = 0; gBase.drawRect(left, top, w, h); } }