/*******************************************************************************
* 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.comp;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import com.cburch.logisim.circuit.Circuit;
import com.cburch.logisim.circuit.CircuitState;
import com.cburch.logisim.circuit.WireSet;
import com.cburch.logisim.data.AttributeSet;
import com.cburch.logisim.data.Bounds;
import com.cburch.logisim.data.Direction;
import com.cburch.logisim.data.Location;
import com.cburch.logisim.instance.InstancePainter;
import com.cburch.logisim.prefs.AppPreferences;
import com.cburch.logisim.util.GraphicsUtil;
public class ComponentDrawContext {
private static final int PIN_OFFS = 2;
private static final int PIN_RAD = 4;
private java.awt.Component dest;
private Circuit circuit;
private CircuitState circuitState;
private Graphics base;
private Graphics g;
private boolean showState;
private boolean showColor;
private boolean printView;
private WireSet highlightedWires;
private InstancePainter instancePainter;
public ComponentDrawContext(java.awt.Component dest, Circuit circuit,
CircuitState circuitState, Graphics base, Graphics g) {
this(dest, circuit, circuitState, base, g, false);
}
public ComponentDrawContext(java.awt.Component dest, Circuit circuit,
CircuitState circuitState, Graphics base, Graphics g,
boolean printView) {
this.dest = dest;
this.circuit = circuit;
this.circuitState = circuitState;
this.base = base;
this.g = g;
this.showState = true;
this.showColor = true;
this.printView = printView;
this.highlightedWires = WireSet.EMPTY;
this.instancePainter = new InstancePainter(this, null);
}
//
// helper methods
//
public void drawBounds(Component comp) {
GraphicsUtil.switchToWidth(g, 2);
g.setColor(Color.BLACK);
Bounds bds = comp.getBounds();
g.drawRect(bds.getX(), bds.getY(), bds.getWidth(), bds.getHeight());
GraphicsUtil.switchToWidth(g, 1);
}
public void drawClock(Component comp, int i, Direction dir) {
Color curColor = g.getColor();
g.setColor(Color.BLACK);
GraphicsUtil.switchToWidth(g, 2);
EndData e = comp.getEnd(i);
Location pt = e.getLocation();
int x = pt.getX();
int y = pt.getY();
final int CLK_SZ = 4;
final int CLK_SZD = CLK_SZ - 1;
if (dir == Direction.NORTH) {
g.drawLine(x - CLK_SZD, y - 1, x, y - CLK_SZ);
g.drawLine(x + CLK_SZD, y - 1, x, y - CLK_SZ);
} else if (dir == Direction.SOUTH) {
g.drawLine(x - CLK_SZD, y + 1, x, y + CLK_SZ);
g.drawLine(x + CLK_SZD, y + 1, x, y + CLK_SZ);
} else if (dir == Direction.EAST) {
g.drawLine(x + 1, y - CLK_SZD, x + CLK_SZ, y);
g.drawLine(x + 1, y + CLK_SZD, x + CLK_SZ, y);
} else if (dir == Direction.WEST) {
g.drawLine(x - 1, y - CLK_SZD, x - CLK_SZ, y);
g.drawLine(x - 1, y + CLK_SZD, x - CLK_SZ, y);
}
g.setColor(curColor);
GraphicsUtil.switchToWidth(g, 1);
}
public void drawClockSymbol(Component comp, int xpos, int ypos) {
GraphicsUtil.switchToWidth(g, 2);
g.drawLine(xpos, ypos - 4, xpos + 8, ypos);
g.drawLine(xpos, ypos + 4, xpos + 8, ypos);
GraphicsUtil.switchToWidth(g, 1);
}
public void drawDongle(int x, int y) {
GraphicsUtil.switchToWidth(g, 2);
g.drawOval(x - 4, y - 4, 9, 9);
}
public void drawHandle(int x, int y) {
g.setColor(Color.white);
g.fillRect(x - 3, y - 3, 7, 7);
g.setColor(Color.black);
g.drawRect(x - 3, y - 3, 7, 7);
}
public void drawHandle(Location loc) {
drawHandle(loc.getX(), loc.getY());
}
public void drawHandles(Component comp) {
Bounds b = comp.getBounds(g);
int left = b.getX();
int right = left + b.getWidth();
int top = b.getY();
int bot = top + b.getHeight();
drawHandle(right, top);
drawHandle(left, bot);
drawHandle(right, bot);
drawHandle(left, top);
}
public void drawPin(Component comp, int i) {
EndData e = comp.getEnd(i);
Location pt = e.getLocation();
Color curColor = g.getColor();
if (getShowState()) {
CircuitState state = getCircuitState();
g.setColor(state.getValue(pt).getColor());
} else {
g.setColor(Color.BLACK);
}
g.fillOval(pt.getX() - PIN_OFFS, pt.getY() - PIN_OFFS, PIN_RAD, PIN_RAD);
g.setColor(curColor);
}
public void drawPin(Component comp, int i, String label, Direction dir) {
Color curColor = g.getColor();
if (i < 0 || i >= comp.getEnds().size())
return;
EndData e = comp.getEnd(i);
Location pt = e.getLocation();
int x = pt.getX();
int y = pt.getY();
if (getShowState()) {
CircuitState state = getCircuitState();
g.setColor(state.getValue(pt).getColor());
} else {
g.setColor(Color.BLACK);
}
g.fillOval(x - PIN_OFFS, y - PIN_OFFS, PIN_RAD, PIN_RAD);
g.setColor(curColor);
if (dir == Direction.EAST) {
GraphicsUtil.drawText(g, label, x + 3, y, GraphicsUtil.H_LEFT,
GraphicsUtil.V_CENTER);
} else if (dir == Direction.WEST) {
GraphicsUtil.drawText(g, label, x - 3, y, GraphicsUtil.H_RIGHT,
GraphicsUtil.V_CENTER);
} else if (dir == Direction.SOUTH) {
GraphicsUtil.drawText(g, label, x, y - 3, GraphicsUtil.H_CENTER,
GraphicsUtil.V_BASELINE);
} else if (dir == Direction.NORTH) {
GraphicsUtil.drawText(g, label, x, y + 3, GraphicsUtil.H_CENTER,
GraphicsUtil.V_TOP);
}
}
public void drawPins(Component comp) {
Color curColor = g.getColor();
for (EndData e : comp.getEnds()) {
Location pt = e.getLocation();
if (getShowState()) {
CircuitState state = getCircuitState();
g.setColor(state.getValue(pt).getColor());
} else {
g.setColor(Color.BLACK);
}
g.fillOval(pt.getX() - PIN_OFFS, pt.getY() - PIN_OFFS, PIN_RAD,
PIN_RAD);
}
g.setColor(curColor);
}
public void drawRectangle(Component comp) {
drawRectangle(comp, "");
}
public void drawRectangle(Component comp, String label) {
Bounds bds = comp.getBounds(g);
drawRectangle(bds.getX(), bds.getY(), bds.getWidth(), bds.getHeight(),
label);
}
public void drawRectangle(ComponentFactory source, int x, int y,
AttributeSet attrs, String label) {
Bounds bds = source.getOffsetBounds(attrs);
drawRectangle(source, x + bds.getX(), y + bds.getY(), bds.getWidth(),
bds.getHeight(), label);
}
public void drawRectangle(ComponentFactory source, int x, int y, int width,
int height, String label) {
GraphicsUtil.switchToWidth(g, 2);
g.drawRect(x + 1, y + 1, width - 1, height - 1);
if (label != null && !label.equals("")) {
FontMetrics fm = base.getFontMetrics(g.getFont());
int lwid = fm.stringWidth(label);
if (height > 20) { // centered at top edge
g.drawString(label, x + (width - lwid) / 2,
y + 2 + fm.getAscent());
} else { // centered overall
g.drawString(label, x + (width - lwid) / 2,
y + (height + fm.getAscent()) / 2 - 1);
}
}
}
public void drawRectangle(int x, int y, int width, int height, String label) {
GraphicsUtil.switchToWidth(g, 2);
g.drawRect(x, y, width, height);
if (label != null && !label.equals("")) {
FontMetrics fm = base.getFontMetrics(g.getFont());
int lwid = fm.stringWidth(label);
if (height > 20) { // centered at top edge
g.drawString(label, x + (width - lwid) / 2,
y + 2 + fm.getAscent());
} else { // centered overall
g.drawString(label, x + (width - lwid) / 2,
y + (height + fm.getAscent()) / 2 - 1);
}
}
}
public Circuit getCircuit() {
return circuit;
}
public CircuitState getCircuitState() {
return circuitState;
}
public java.awt.Component getDestination() {
return dest;
}
public Object getGateShape() {
return AppPreferences.GATE_SHAPE.get();
}
public Graphics getGraphics() {
return g;
}
public WireSet getHighlightedWires() {
return highlightedWires;
}
public InstancePainter getInstancePainter() {
return instancePainter;
}
public boolean getShowState() {
return !printView && showState;
}
public boolean isPrintView() {
return printView;
}
public void setGraphics(Graphics g) {
this.g = g;
}
public void setHighlightedWires(WireSet value) {
this.highlightedWires = value == null ? WireSet.EMPTY : value;
}
public void setShowColor(boolean value) {
showColor = value;
}
public void setShowState(boolean value) {
showState = value;
}
public boolean shouldDrawColor() {
return !printView && showColor;
}
}