/*******************************************************************************
* This file is part of logisim-evolution.
*
* logisim-evolution is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* logisim-evolution is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with logisim-evolution. If not, see <http://www.gnu.org/licenses/>.
*
* Original code by Carl Burch (http://www.cburch.com), 2011.
* Subsequent modifications by :
* + Haute École Spécialisée Bernoise
* http://www.bfh.ch
* + Haute École du paysage, d'ingénierie et d'architecture de Genève
* http://hepia.hesge.ch/
* + Haute École d'Ingénierie et de Gestion du Canton de Vaud
* http://www.heig-vd.ch/
* The project is currently maintained by :
* + REDS Institute - HEIG-VD
* Yverdon-les-Bains, Switzerland
* http://reds.heig-vd.ch
*******************************************************************************/
package com.cburch.logisim.circuit.appear;
import java.awt.Color;
import java.awt.Graphics;
import java.util.List;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.cburch.draw.model.CanvasObject;
import com.cburch.draw.model.Handle;
import com.cburch.draw.model.HandleGesture;
import com.cburch.logisim.data.Bounds;
import com.cburch.logisim.data.Location;
import com.cburch.logisim.instance.Instance;
import com.cburch.logisim.std.wiring.Pin;
import com.cburch.logisim.util.UnmodifiableList;
public class AppearancePort extends AppearanceElement {
private static final int INPUT_RADIUS = 4;
private static final int OUTPUT_RADIUS = 5;
private static final int MINOR_RADIUS = 2;
public static final Color COLOR = Color.BLUE;
private Instance pin;
public AppearancePort(Location location, Instance pin) {
super(location);
this.pin = pin;
}
@Override
public boolean contains(Location loc, boolean assumeFilled) {
if (isInput()) {
return getBounds().contains(loc);
} else {
return super.isInCircle(loc, OUTPUT_RADIUS);
}
}
@Override
public Bounds getBounds() {
int r = isInput() ? INPUT_RADIUS : OUTPUT_RADIUS;
return super.getBounds(r);
}
@Override
public String getDisplayName() {
return Strings.get("circuitPort");
}
@Override
public List<Handle> getHandles(HandleGesture gesture) {
Location loc = getLocation();
int r = isInput() ? INPUT_RADIUS : OUTPUT_RADIUS;
return UnmodifiableList.create(new Handle[] {
new Handle(this, loc.translate(-r, -r)),
new Handle(this, loc.translate(r, -r)),
new Handle(this, loc.translate(r, r)),
new Handle(this, loc.translate(-r, r)) });
}
public Instance getPin() {
return pin;
}
private boolean isInput() {
Instance p = pin;
return p == null || Pin.FACTORY.isInputPin(p);
}
@Override
public boolean matches(CanvasObject other) {
if (other instanceof AppearancePort) {
AppearancePort that = (AppearancePort) other;
return this.matches(that) && this.pin == that.pin;
} else {
return false;
}
}
@Override
public int matchesHashCode() {
return super.matchesHashCode() + pin.hashCode();
}
@Override
public void paint(Graphics g, HandleGesture gesture) {
Location location = getLocation();
int x = location.getX();
int y = location.getY();
g.setColor(COLOR);
if (isInput()) {
int r = INPUT_RADIUS;
g.drawRect(x - r, y - r, 2 * r, 2 * r);
} else {
int r = OUTPUT_RADIUS;
g.drawOval(x - r, y - r, 2 * r, 2 * r);
}
g.fillOval(x - MINOR_RADIUS, y - MINOR_RADIUS, 2 * MINOR_RADIUS,
2 * MINOR_RADIUS);
}
void setPin(Instance value) {
pin = value;
}
@Override
public Element toSvgElement(Document doc) {
Location loc = getLocation();
Location pinLoc = pin.getLocation();
Element ret = doc.createElement("circ-port");
int r = isInput() ? INPUT_RADIUS : OUTPUT_RADIUS;
ret.setAttribute("x", "" + (loc.getX() - r));
ret.setAttribute("y", "" + (loc.getY() - r));
ret.setAttribute("width", "" + 2 * r);
ret.setAttribute("height", "" + 2 * r);
ret.setAttribute("pin", "" + pinLoc.getX() + "," + pinLoc.getY());
return ret;
}
}