outline mode

improved auto-create for pads
This commit is contained in:
bancika
2011-03-05 19:53:19 +00:00
parent 79c29dc349
commit 943d123ca9
46 changed files with 546 additions and 224 deletions
@@ -32,5 +32,9 @@ public enum DrawOption {
/**
* Anti-aliasing is used when drawing.
*/
ANTIALIASING;
ANTIALIASING,
/**
* Draw components in outline mode.
*/
OUTLINE_MODE;
}
@@ -43,6 +43,8 @@ public interface IPlugInPort {
public static final String AUTO_EDIT_KEY = "autoEdit";
public static final String ABNORMAL_EXIT_KEY = "abnormalExit";
public static final String WHEEL_ZOOM_KEY = "wheelZoom";
public static final String OUTLINE_KEY = "outline";
public static final String THEME_KEY = "theme";
/**
* Returns size of the canvas that takes project dimensions into account as
@@ -63,8 +63,8 @@ public abstract class AbstractCurvedComponent<T> extends AbstractTransparentComp
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, Project project,
IDrawingObserver drawingObserver) {
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
@@ -13,14 +13,19 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import org.diylc.common.Display;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.core.ComponentState;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
import com.diyfever.gui.miscutils.ConfigurationManager;
/**
* Base class for all leaded components such as resistors or capacitors. Has two
@@ -45,7 +50,7 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
protected Color bodyColor = Color.white;
protected Color borderColor = Color.black;
protected Color labelColor = LABEL_COLOR;
protected Display display = Display.NAME;
protected Display display = Display.VALUE;
protected AbstractLeadedComponent() {
super();
@@ -60,8 +65,8 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, Project project,
IDrawingObserver drawingObserver) {
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
double distance = points[0].distance(points[1]);
Shape shape = getBodyShape();
// If there's no body, just draw the line connecting the ending points.
@@ -74,13 +79,32 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
int width = getClosestOdd(this.width.convertToPixels());
Shape body = new Ellipse2D.Double(points[0].x - width / 2, points[0].y - width / 2,
width, width);
g2d.setColor(bodyColor);
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
/ MAX_ALPHA));
}
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : bodyColor);
g2d.fill(body);
Color finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : borderColor;
g2d.setComposite(oldComposite);
Color finalBorderColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
.getOutlineColor();
} else {
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: borderColor;
}
g2d.setColor(finalBorderColor);
g2d.draw(body);
drawLead(g2d, componentState);
if (!outlineMode) {
drawLead(g2d, componentState);
}
} else {
// Normal mode with component body in the center and two lead parts.
Rectangle shapeRect = shape.getBounds();
@@ -99,23 +123,42 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
}
if (bodyColor != null) {
if (bodyColor != null) {
g2d.setColor(bodyColor);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : bodyColor);
g2d.fill(shape);
}
}
decorateComponentBody(g2d);
decorateComponentBody(g2d, outlineMode);
g2d.setComposite(oldComposite);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
Color finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : borderColor;
Color finalBorderColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
.getOutlineColor();
} else {
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: borderColor;
}
g2d.setColor(finalBorderColor);
g2d.draw(shape);
// Draw label.
g2d.setFont(LABEL_FONT);
Color finalLabelFont = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: labelColor;
g2d.setColor(finalLabelFont);
Color finalLabelColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
.getOutlineColor();
} else {
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: labelColor;
}
g2d.setColor(finalLabelColor);
FontMetrics fontMetrics = g2d.getFontMetrics();
String label = display == Display.NAME ? getName() : getValue().toString();
// Adjust label angle if needed to make sure that it's readable.
@@ -128,30 +171,31 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
calculateLabelYCoordinate(shapeRect, textRect, fontMetrics));
// Go back to the original transformation to draw leads.
g2d.setTransform(oldTransform);
int leadThickness = getClosestOdd(getLeadThickness());
double leadLength = (distance - shapeRect.width) / 2 - leadThickness / 2;
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness));
Color leadColor = shouldShadeLeads() ? getLeadColor(componentState).darker()
: getLeadColor(componentState);
g2d.setColor(leadColor);
int endX = (int) (points[0].x + Math.cos(theta) * leadLength);
int endY = (int) Math.round(points[0].y + Math.sin(theta) * leadLength);
g2d.drawLine(points[0].x, points[0].y, endX, endY);
endX = (int) (points[1].x + Math.cos(theta - Math.PI) * leadLength);
endY = (int) Math.round(points[1].y + Math.sin(theta - Math.PI) * leadLength);
g2d.drawLine(points[1].x, points[1].y, endX, endY);
if (shouldShadeLeads()) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness - 2));
leadColor = getLeadColor(componentState);
if (!outlineMode) {
g2d.setTransform(oldTransform);
int leadThickness = getClosestOdd(getLeadThickness());
double leadLength = (distance - shapeRect.width) / 2 - leadThickness / 2;
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness));
Color leadColor = shouldShadeLeads() ? getLeadColor(componentState).darker()
: getLeadColor(componentState);
g2d.setColor(leadColor);
g2d.drawLine(points[0].x, points[0].y, (int) (points[0].x + Math.cos(theta)
* leadLength), (int) (points[0].y + Math.sin(theta) * leadLength));
g2d
.drawLine(points[1].x, points[1].y, (int) (points[1].x + Math.cos(theta
- Math.PI)
* leadLength), (int) (points[1].y + Math.sin(theta - Math.PI)
* leadLength));
int endX = (int) (points[0].x + Math.cos(theta) * leadLength);
int endY = (int) Math.round(points[0].y + Math.sin(theta) * leadLength);
g2d.drawLine(points[0].x, points[0].y, endX, endY);
endX = (int) (points[1].x + Math.cos(theta - Math.PI) * leadLength);
endY = (int) Math.round(points[1].y + Math.sin(theta - Math.PI) * leadLength);
g2d.drawLine(points[1].x, points[1].y, endX, endY);
if (shouldShadeLeads()) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness - 2));
leadColor = getLeadColor(componentState);
g2d.setColor(leadColor);
g2d.drawLine(points[0].x, points[0].y, (int) (points[0].x + Math.cos(theta)
* leadLength), (int) (points[0].y + Math.sin(theta) * leadLength));
g2d.drawLine(points[1].x, points[1].y, (int) (points[1].x + Math.cos(theta
- Math.PI)
* leadLength), (int) (points[1].y + Math.sin(theta - Math.PI)
* leadLength));
}
}
}
}
@@ -170,7 +214,7 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
}
}
protected void decorateComponentBody(Graphics2D g2d) {
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
// Do nothing.
}
@@ -103,10 +103,11 @@ public interface IDIYComponent<T> extends Serializable {
*
* @param g2d
* @param componentState
* @param outlineMode
* @param project
* @param drawingObserver
*/
void draw(Graphics2D g2d, ComponentState componentState, Project project,
void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver);
/**
@@ -10,12 +10,14 @@ public class Theme implements Serializable {
private String name;
private Color bgColor;
private Color gridColor;
private Color outlineColor;
public Theme(String name, Color bgColor, Color gridColor) {
public Theme(String name, Color bgColor, Color gridColor, Color outlineColor) {
super();
this.name = name;
this.bgColor = bgColor;
this.gridColor = gridColor;
this.outlineColor = outlineColor;
}
public String getName() {
@@ -30,12 +32,17 @@ public class Theme implements Serializable {
return gridColor;
}
public Color getOutlineColor() {
return outlineColor;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((bgColor == null) ? 0 : bgColor.hashCode());
result = prime * result + ((gridColor == null) ? 0 : gridColor.hashCode());
result = prime * result + ((outlineColor == null) ? 0 : outlineColor.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@@ -59,6 +66,11 @@ public class Theme implements Serializable {
return false;
} else if (!gridColor.equals(other.gridColor))
return false;
if (outlineColor == null) {
if (other.outlineColor != null)
return false;
} else if (!outlineColor.equals(other.outlineColor))
return false;
if (name == null) {
if (other.name != null)
return false;
@@ -46,14 +46,14 @@ public class DrawingManager {
public static int CONTROL_POINT_SIZE = 7;
public static final String ZOOM_KEY = "zoom";
public static final String THEME_KEY = "theme";
public static String DEBUG_COMPONENT_AREAS = "org.diylc.debugComponentAreas";
public static Color GRID_COLOR = new Color(240, 240, 240);
public static Color CONTROL_POINT_COLOR = Color.black;
public static Color CONTROL_POINT_COLOR = Color.blue;
public static Color SELECTED_CONTROL_POINT_COLOR = Color.green;
private Theme theme = new Theme("Light", Constants.CANVAS_COLOR, GRID_COLOR);
private Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
// Keeps Area object of each drawn component.
private Map<IDIYComponent<?>, Area> componentAreaMap;
@@ -80,10 +80,6 @@ public class DrawingManager {
String debugComponentAreasStr = System.getProperty(DEBUG_COMPONENT_AREAS);
debugComponentAreas = debugComponentAreasStr != null
&& debugComponentAreasStr.equalsIgnoreCase("true");
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(THEME_KEY, null);
if (theme != null) {
this.theme = theme;
}
}
/**
@@ -220,7 +216,8 @@ public class DrawingManager {
}
// Draw the component through the g2dWrapper.
try {
component.draw(g2dWrapper, state, project, g2dWrapper);
component.draw(g2dWrapper, state, drawOptions.contains(DrawOption.OUTLINE_MODE),
project, g2dWrapper);
} catch (Exception e) {
LOG.error("Error drawing " + component.getName(), e);
failedComponents.add(component);
@@ -235,7 +232,7 @@ public class DrawingManager {
// Draw control points.
if (drawOptions.contains(DrawOption.CONTROL_POINTS)) {
// Draw unselected points first to make sure they are below.
if (dragInProgress) {
if (dragInProgress || drawOptions.contains(DrawOption.OUTLINE_MODE)) {
for (IDIYComponent<?> component : project.getComponents()) {
for (int i = 0; i < component.getControlPointCount(); i++) {
VisibilityPolicy visibilityPolicy = component
@@ -247,7 +244,6 @@ public class DrawingManager {
&& !selectedComponents.contains(component) && component
.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS))) {
g2dWrapper.setColor(CONTROL_POINT_COLOR);
Point controlPoint = component.getControlPoint(i);
int pointSize = CONTROL_POINT_SIZE - 2;
g2dWrapper.fillOval(controlPoint.x - pointSize / 2, controlPoint.y
@@ -283,7 +279,8 @@ public class DrawingManager {
g2dWrapper.startedDrawingComponent();
g2dWrapper.setComposite(slotComposite);
try {
componentSlot.draw(g2dWrapper, ComponentState.NORMAL, project, g2dWrapper);
componentSlot.draw(g2dWrapper, ComponentState.NORMAL, drawOptions
.contains(DrawOption.OUTLINE_MODE), project, g2dWrapper);
} catch (Exception e) {
LOG.error("Error drawing " + componentSlot.getName(), e);
failedComponents.add(componentSlot);
@@ -393,7 +390,7 @@ public class DrawingManager {
public void setTheme(Theme theme) {
this.theme = theme;
ConfigurationManager.getInstance().writeValue(THEME_KEY, theme);
ConfigurationManager.getInstance().writeValue(IPlugInPort.THEME_KEY, theme);
messageDispatcher.dispatchMessage(EventType.REPAINT);
}
}
@@ -800,7 +800,8 @@ public class Presenter implements IPlugInPort {
for (int j = i + 1; j < controlPoints.length; j++) {
if (controlPoints[i] != null && controlPoints[j] != null
&& controlPoints[i].equals(controlPoints[j])) {
// Control points collision detected, cannot make this move.
// Control points collision detected, cannot make
// this move.
return true;
}
}
@@ -1171,13 +1172,25 @@ public class Presenter implements IPlugInPort {
currentProject.getComponents().add(component);
}
if (canCreatePads
&& ConfigurationManager.getInstance().readBoolean(IPlugInPort.AUTO_PADS_KEY, false)) {
&& ConfigurationManager.getInstance().readBoolean(IPlugInPort.AUTO_PADS_KEY, false)
&& !(component instanceof SolderPad)) {
ComponentType padType = ComponentProcessor.getInstance().extractComponentTypeFrom(
SolderPad.class);
for (int i = 0; i < component.getControlPointCount(); i++) {
if (component.isControlPointSticky(i)) {
SolderPad pad = new SolderPad();
pad.setControlPoint(component.getControlPoint(i), 0);
addComponent(pad, ComponentProcessor.getInstance().extractComponentTypeFrom(
SolderPad.class), false);
try {
IDIYComponent<?> pad = instantiationManager.instantiateComponent(padType,
component.getControlPoint(i), currentProject);
pad.setControlPoint(component.getControlPoint(i), 0);
addComponent(pad, padType, false);
} catch (Exception e) {
LOG.warn("Could not auto-create solder pad", e);
}
// SolderPad pad = new SolderPad();
// pad.setControlPoint(component.getControlPoint(i), 0);
// addComponent(pad,
// ComponentProcessor.getInstance().extractComponentTypeFrom(
// SolderPad.class), false);
}
}
}
@@ -21,6 +21,7 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.VolatileImage;
import java.util.EnumSet;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
@@ -47,11 +48,11 @@ class CanvasPanel extends JComponent implements Autoscroll {
private static boolean USE_HARDWARE_ACCELLERATION = false;
static final EnumSet<DrawOption> DRAW_OPTIONS = EnumSet.of(DrawOption.GRID,
DrawOption.SELECTION, DrawOption.ZOOM, DrawOption.CONTROL_POINTS);
static final EnumSet<DrawOption> DRAW_OPTIONS_ANTI_ALIASING = EnumSet.of(DrawOption.GRID,
DrawOption.SELECTION, DrawOption.ZOOM, DrawOption.ANTIALIASING,
DrawOption.CONTROL_POINTS);
// static final EnumSet<DrawOption> DRAW_OPTIONS = EnumSet.of(DrawOption.GRID,
// DrawOption.SELECTION, DrawOption.ZOOM, DrawOption.CONTROL_POINTS);
// static final EnumSet<DrawOption> DRAW_OPTIONS_ANTI_ALIASING = EnumSet.of(DrawOption.GRID,
// DrawOption.SELECTION, DrawOption.ZOOM, DrawOption.ANTIALIASING,
// DrawOption.CONTROL_POINTS);
public CanvasPanel(IPlugInPort plugInPort) {
super();
@@ -114,9 +115,15 @@ class CanvasPanel extends JComponent implements Autoscroll {
}
Graphics2D g2d = (Graphics2D) bufferImage.getGraphics();
g2d.setClip(getVisibleRect());
plugInPort.draw(g2d, ConfigurationManager.getInstance().readBoolean(
IPlugInPort.ANTI_ALIASING_KEY, true) ? DRAW_OPTIONS_ANTI_ALIASING : DRAW_OPTIONS,
null);
Set<DrawOption> drawOptions = EnumSet.of(DrawOption.GRID, DrawOption.SELECTION,
DrawOption.ZOOM, DrawOption.CONTROL_POINTS);
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.ANTI_ALIASING_KEY, true)) {
drawOptions.add(DrawOption.ANTIALIASING);
}
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.OUTLINE_KEY, false)) {
drawOptions.add(DrawOption.OUTLINE_MODE);
}
plugInPort.draw(g2d, drawOptions, null);
if (USE_HARDWARE_ACCELLERATION) {
VolatileImage volatileImage = (VolatileImage) bufferImage;
do {
@@ -52,6 +52,8 @@ public class ConfigPlugin implements IPlugIn {
"Hi-Quality Rendering", IPlugInPort.HI_QUALITY_RENDER_KEY, false), CONFIG_MENU);
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
"Mouse Wheel Zoom", IPlugInPort.WHEEL_ZOOM_KEY, false), CONFIG_MENU);
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
"Outline Mode", IPlugInPort.OUTLINE_KEY, false), CONFIG_MENU);
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
"Snap to Grid", IPlugInPort.SNAP_TO_GRID_KEY, true), CONFIG_MENU);
swingUI.injectMenuAction(ActionFactory.getInstance().createConfigAction(plugInPort,
@@ -33,16 +33,19 @@ public class ProjectDrawingProvider implements IDrawingProvider {
@Override
public void draw(Graphics g) {
EnumSet<DrawOption> options = EnumSet.of(DrawOption.ANTIALIASING);
EnumSet<DrawOption> drawOptions = EnumSet.of(DrawOption.ANTIALIASING);
if (useZoom) {
options.add(DrawOption.ZOOM);
drawOptions.add(DrawOption.ZOOM);
}
if (showGridWhenNeeded
&& ConfigurationManager.getInstance().readBoolean(IPlugInPort.EXPORT_GRID_KEY,
false)) {
options.add(DrawOption.GRID);
drawOptions.add(DrawOption.GRID);
}
plugInPort.draw((Graphics2D) g, options, null);
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.OUTLINE_KEY, false)) {
drawOptions.add(DrawOption.OUTLINE_MODE);
}
plugInPort.draw((Graphics2D) g, drawOptions, null);
}
@Override
@@ -5,6 +5,8 @@ import java.awt.Color;
import java.awt.Stroke;
import java.awt.Toolkit;
import org.diylc.core.Theme;
public class Constants {
public static final int PIXELS_PER_INCH = 200;
@@ -15,4 +17,9 @@ public class Constants {
public static final Stroke DASHED_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10f, new float[] { 2.0f }, 0.0f);
public static final Theme DEFAULT_THEME = new Theme("Light", Constants.CANVAS_COLOR, new Color(
240, 240, 240), Color.black);
public static final Color TRANSPARENT_COLOR = new Color(0, 0, 0, 0);
}