added layer locking

added eyelet board
This commit is contained in:
bancika
2011-01-22 13:17:43 +00:00
parent 99d85a2d1f
commit 664bf91852
15 changed files with 372 additions and 67 deletions
@@ -75,5 +75,7 @@ public enum EventType {
* Called when mouse cursor is moved. Point object is passed, containing the
* current cursor location (not taking zoom into account).
*/
MOUSE_MOVED;
MOUSE_MOVED,
LAYER_STATE_CHANGED;
;
}
@@ -34,6 +34,8 @@ import com.diyfever.gui.update.VersionNumber;
* @see EventType
*/
public interface IPlugInPort {
public static final String CHECK_BOX_MENU_ITEM = "org.diylc.checkBoxMenuItem";
/**
* Returns size of the canvas that takes project dimensions into account as
@@ -349,4 +351,6 @@ public interface IPlugInPort {
* Ungroups all selected components.
*/
void ungroupSelectedComponents();
void setLayerLocked(int layerZOrder, boolean locked);
}
@@ -1,26 +1,33 @@
package org.diylc.common;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Stroke;
import java.util.HashMap;
import java.util.Map;
/**
* Repository for object that may be reused, such as {@link Stroke} or
* {@link AlphaComposite}.
*
* @author Branislav Stojkovic
*/
public class ObjectCache {
private static ObjectCache instance;
public static ObjectCache getInstance() {
if (instance == null) {
instance = new ObjectCache();
}
return instance;
}
private ObjectCache() {
}
private Map<Integer, Stroke> basicStrokeMap = new HashMap<Integer, Stroke>();
public Stroke fetchBasicStroke(int width) {
if (basicStrokeMap.containsKey(width)) {
return basicStrokeMap.get(width);
@@ -34,10 +34,12 @@ public class Project implements Serializable {
private Size gridSpacing;
private List<IDIYComponent<?>> components;
private Set<Set<IDIYComponent<?>>> groups;
private Set<Integer> lockedLayers;
public Project() {
components = new ArrayList<IDIYComponent<?>>();
groups = new HashSet<Set<IDIYComponent<?>>>();
lockedLayers = new HashSet<Integer>();
title = DEFAULT_TITLE;
author = System.getProperty("user.name");
width = DEFAULT_WIDTH;
@@ -45,19 +47,6 @@ public class Project implements Serializable {
gridSpacing = DEFAULT_GRID_SPACING;
}
public Project(String title, String author, String description, Size width, Size height,
Size gridSpacing, List<IDIYComponent<?>> components, Set<Set<IDIYComponent<?>>> groups) {
super();
this.title = title;
this.author = author;
this.description = description;
this.width = width;
this.height = height;
this.gridSpacing = gridSpacing;
this.components = components;
this.groups = groups;
}
@EditableProperty(defaultable = false)
public String getTitle() {
return title;
@@ -129,6 +118,10 @@ public class Project implements Serializable {
public Set<Set<IDIYComponent<?>>> getGroups() {
return groups;
}
public Set<Integer> getLockedLayers() {
return lockedLayers;
}
@Override
public int hashCode() {
@@ -184,6 +177,11 @@ public class Project implements Serializable {
return false;
return true;
}
@Override
public String toString() {
return title;
}
// @Override
// public Project clone() throws CloneNotSupportedException {
@@ -15,6 +15,7 @@ import java.util.Map;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
@@ -33,6 +34,7 @@ import org.diylc.plugins.canvas.CanvasPlugin;
import org.diylc.plugins.clipboard.EditMenuPlugin;
import org.diylc.plugins.file.FileMenuPlugin;
import org.diylc.plugins.help.HelpMenuPlugin;
import org.diylc.plugins.layers.LayersMenuPlugin;
import org.diylc.plugins.statusbar.StatusBar;
import org.diylc.plugins.toolbox.ToolBox;
import org.diylc.presenter.Presenter;
@@ -69,6 +71,7 @@ public class MainFrame extends JFrame implements IView {
presenter.installPlugin(new ToolBox());
presenter.installPlugin(new FileMenuPlugin());
presenter.installPlugin(new EditMenuPlugin());
presenter.installPlugin(new LayersMenuPlugin());
// presenter.installPlugin(new OnlineManager());
presenter.installPlugin(new HelpMenuPlugin());
@@ -195,7 +198,12 @@ public class MainFrame extends JFrame implements IView {
if (action == null) {
menu.addSeparator();
} else {
menu.add(action);
Boolean isCheckBox = (Boolean) action.getValue(IPlugInPort.CHECK_BOX_MENU_ITEM);
if (isCheckBox != null && isCheckBox) {
menu.add(new JCheckBoxMenuItem(action));
} else {
menu.add(action);
}
}
}
@@ -0,0 +1,51 @@
package org.diylc.gui.editor;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import org.diylc.common.PropertyWrapper;
public class FontEditor extends JLabel {
private static final long serialVersionUID = 1L;
public FontEditor(final PropertyWrapper property) {
super("Click to edit");
setOpaque(true);
setHorizontalAlignment(SwingConstants.CENTER);
setBorder(BorderFactory.createEtchedBorder());
setBackground((Color) property.getValue());
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
// JFo
Color newColor = JColorChooser.showDialog(FontEditor.this, "Choose Color",
getBackground());
if (newColor != null) {
property.setValue(newColor);
setBackground(newColor);
}
}
});
}
@Override
public void setBackground(Color bg) {
if (bg.getRed() < 127 || bg.getBlue() < 127 || bg.getGreen() < 127) {
setForeground(Color.white);
} else {
setForeground(Color.black);
}
super.setBackground(bg);
}
}
@@ -0,0 +1,89 @@
package org.diylc.plugins.layers;
import java.awt.event.ActionEvent;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.Action;
import org.diylc.common.EventType;
import org.diylc.common.IPlugIn;
import org.diylc.common.IPlugInPort;
import org.diylc.core.IDIYComponent;
public class LayersMenuPlugin implements IPlugIn {
private static final String LOCK_LAYERS_TITLE = "Lock Layers";
private IPlugInPort plugInPort;
private Map<Layer, Action> lockActionMap;
public LayersMenuPlugin() {
}
@Override
public void connect(IPlugInPort plugInPort) {
this.plugInPort = plugInPort;
lockActionMap = new HashMap<Layer, Action>();
for (Layer layer : Layer.values()) {
final int zOrder = layer.getZOrder();
AbstractAction action = new AbstractAction(layer.getTitle()) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
LayersMenuPlugin.this.plugInPort.setLayerLocked(zOrder, true);
}
};
action.putValue(IPlugInPort.CHECK_BOX_MENU_ITEM, true);
lockActionMap.put(layer, action);
plugInPort.injectMenuAction(action, LOCK_LAYERS_TITLE);
}
}
@Override
public EnumSet<EventType> getSubscribedEventTypes() {
return EnumSet.of(EventType.LAYER_STATE_CHANGED);
}
@Override
public void processMessage(EventType eventType, Object... params) {
if (eventType == EventType.LAYER_STATE_CHANGED) {
Set<Integer> lockedLayers = (Set<Integer>) params[0];
for (Layer layer : Layer.values()) {
lockActionMap.get(layer).putValue(Action.SELECTED_KEY,
lockedLayers.contains(layer.getZOrder()));
}
}
}
static enum Layer {
BELOW_CHASSIS("Below Chassis", IDIYComponent.BELOW_CHASSIS), CHASSIS("Chassis",
IDIYComponent.CHASSIS), ABOVE_CHASSIS("Above Chassis", IDIYComponent.ABOVE_CHASSIS), BELOW_BOARD(
"Below Board", IDIYComponent.BELOW_BOARD), BOARD("Board", IDIYComponent.BOARD), ABOVE_BOARD(
"Above Board", IDIYComponent.ABOVE_BOARD), COMPONENT("Component",
IDIYComponent.COMPONENT), ABOVE_COMPONENT("Above Component",
IDIYComponent.ABOVE_COMPONENT);
String title;
int zOrder;
private Layer(String title, int order) {
this.title = title;
zOrder = order;
}
public String getTitle() {
return title;
}
public int getZOrder() {
return zOrder;
}
}
}
@@ -10,7 +10,6 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Area;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -58,9 +57,10 @@ public class DrawingManager {
private Map<IDIYComponent<?>, ComponentState> lastDrawnStateMap;
private Composite slotComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);
private Composite lockedComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);
private double zoomLevel = 1d;// ConfigurationManager.getInstance().readDouble(ZOOM_KEY,
// 1d);
// 1d);
private MessageDispatcher<EventType> messageDispatcher;
@@ -73,8 +73,8 @@ public class DrawingManager {
public void drawProject(Graphics2D g2d, Project project, Set<DrawOption> drawOptions,
IComponentFiler filter, Rectangle selectionRect, ComponentSelection selectedComponents,
Set<IDIYComponent<?>> groupedComponents, List<Point> controlPointSlot,
IDIYComponent<?> componentSlot, boolean dragInProgress) {
Set<IDIYComponent<?>> lockedComponents, Set<IDIYComponent<?>> groupedComponents,
List<Point> controlPointSlot, IDIYComponent<?> componentSlot, boolean dragInProgress) {
if (project == null) {
return;
}
@@ -155,6 +155,10 @@ public class DrawingManager {
if (!trackArea) {
g2dWrapper.stopTracking();
}
// Draw locked components in a new composite.
if (lockedComponents.contains(component)) {
g2d.setComposite(lockedComposite);
}
// Draw the component through the g2dWrapper.
component.draw(g2dWrapper, state, project, g2dWrapper);
Area area = g2dWrapper.finishedDrawingComponent();
@@ -277,15 +281,6 @@ public class DrawingManager {
return componentAreaMap.get(component);
}
public boolean isCursorOverArea(Point2D cursorPosition) {
for (Map.Entry<IDIYComponent<?>, Area> entry : componentAreaMap.entrySet()) {
if (entry.getValue().contains(cursorPosition)) {
return true;
}
}
return false;
}
public List<IDIYComponent<?>> findComponentsAt(Point point, Project project) {
List<IDIYComponent<?>> components = new ArrayList<IDIYComponent<?>>();
for (Map.Entry<IDIYComponent<?>, Area> entry : componentAreaMap.entrySet()) {
@@ -56,7 +56,7 @@ public class Presenter implements IPlugInPort {
private static final Logger LOG = Logger.getLogger(Presenter.class);
public static final VersionNumber CURRENT_VERSION = new VersionNumber(3, 0, 1);
public static final VersionNumber CURRENT_VERSION = new VersionNumber(3, 0, 3);
public static final String DEFAULTS_KEY_PREFIX = "default.";
public static final String METRIC_KEY = "metric";
@@ -72,6 +72,7 @@ public class Presenter implements IPlugInPort {
// Maps components that have at least one dragged point to set of indices
// that designate which of their control points are being dragged.
private Map<IDIYComponent<?>, Set<Integer>> controlPointMap;
private Set<IDIYComponent<?>> lockedComponents;
// Utilities
private Cloner cloner;
@@ -103,6 +104,7 @@ public class Presenter implements IPlugInPort {
plugIns = new ArrayList<IPlugIn>();
messageDispatcher = new MessageDispatcher<EventType>();
selectedComponents = new ComponentSelection();
lockedComponents = new HashSet<IDIYComponent<?>>();
currentProject = new Project();
cloner = new Cloner();
drawingManager = new DrawingManager(messageDispatcher);
@@ -153,12 +155,17 @@ public class Presenter implements IPlugInPort {
if (instantiationManager.getComponentTypeSlot() == null) {
// Scale point to remove zoom factor.
Point2D scaledPoint = scalePoint(point);
if (drawingManager.isCursorOverArea(scaledPoint)) {
return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
}
if (controlPointMap != null && !controlPointMap.isEmpty()) {
return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
}
for (IDIYComponent<?> component : currentProject.getComponents()) {
if (!isComponentLocked(component)) {
Area area = drawingManager.getComponentArea(component);
if (area != null && area.contains(scaledPoint)) {
return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
}
}
}
}
return Cursor.getDefaultCursor();
}
@@ -181,6 +188,8 @@ public class Presenter implements IPlugInPort {
updateSelection(ComponentSelection.EMPTY_SELECTION);
messageDispatcher.dispatchMessage(EventType.PROJECT_LOADED, project, freshStart);
messageDispatcher.dispatchMessage(EventType.REPAINT);
messageDispatcher.dispatchMessage(EventType.LAYER_STATE_CHANGED, currentProject
.getLockedLayers());
}
@Override
@@ -296,9 +305,9 @@ public class Presenter implements IPlugInPort {
componentSlotToDraw = instantiationManager.getComponentSlot();
}
drawingManager.drawProject(g2d, currentProject, drawOptions, filter, selectionRect,
selectedComponents, groupedComponents, Arrays.asList(instantiationManager
.getFirstControlPoint(), instantiationManager.getPotentialControlPoint()),
componentSlotToDraw, dragInProgress);
selectedComponents, getLockedComponents(), groupedComponents, Arrays.asList(
instantiationManager.getFirstControlPoint(), instantiationManager
.getPotentialControlPoint()), componentSlotToDraw, dragInProgress);
}
@Override
@@ -323,12 +332,20 @@ public class Presenter implements IPlugInPort {
/**
* Finds all components whose areas include the specified {@link Point}.
* Point is <b>not</b> scaled by the zoom factor.
* Point is <b>not</b> scaled by the zoom factor. Components that belong to
* locked layers are ignored.
*
* @return
*/
private List<IDIYComponent<?>> findComponentsAt(Point point) {
return drawingManager.findComponentsAt(point, currentProject);
List<IDIYComponent<?>> components = drawingManager.findComponentsAt(point, currentProject);
Iterator<IDIYComponent<?>> iterator = components.iterator();
while (iterator.hasNext()) {
if (isComponentLocked(iterator.next())) {
iterator.remove();
}
}
return components;
}
@Override
@@ -350,12 +367,12 @@ public class Presenter implements IPlugInPort {
componentTypeSlot, scaledPoint, currentProject);
addComponent(component, componentTypeSlot);
// Select the new component
updateSelection(ComponentSelection.of(component));
// messageDispatcher.dispatchMessage(EventType.SELECTION_CHANGED,
// selectedComponents);
// messageDispatcher.dispatchMessage(EventType.SELECTION_SIZE_CHANGED,
// calculateSelectionDimension());
messageDispatcher.dispatchMessage(EventType.REPAINT);
updateSelection(ComponentSelection.of(component));
} catch (Exception e) {
LOG.error("Error instatiating component of type: "
+ componentTypeSlot.getInstanceClass().getName(), e);
@@ -384,8 +401,9 @@ public class Presenter implements IPlugInPort {
IDIYComponent<?> componentSlot = instantiationManager.getComponentSlot();
componentSlot.setControlPoint(scaledPoint, 1);
addComponent(componentSlot, componentTypeSlot);
// Select the new component
updateSelection(ComponentSelection.of(componentSlot));
// Select the new component if it's not locked.
updateSelection(isComponentLocked(componentSlot) ? ComponentSelection.EMPTY_SELECTION
: ComponentSelection.of(componentSlot));
messageDispatcher.dispatchMessage(EventType.REPAINT);
setNewComponentTypeSlot(null);
}
@@ -685,7 +703,7 @@ public class Presenter implements IPlugInPort {
// Update all points.
for (Map.Entry<IDIYComponent<?>, Set<Integer>> entry : controlPointMap.entrySet()) {
IDIYComponent<?> c = entry.getKey();
drawingManager.invalidateComponent(c);
// drawingManager.invalidateComponent(c);
for (Integer index : entry.getValue()) {
Point p = new Point(c.getControlPoint(index));
p.translate(dx, dy);
@@ -739,9 +757,11 @@ public class Presenter implements IPlugInPort {
}
ComponentSelection newSelection = new ComponentSelection();
for (IDIYComponent<?> component : currentProject.getComponents()) {
Area area = drawingManager.getComponentArea(component);
if ((area != null) && (selectionRect != null) && area.intersects(selectionRect)) {
newSelection.addAll(findAllGroupedComponents(component));
if (!isComponentLocked(component)) {
Area area = drawingManager.getComponentArea(component);
if ((area != null) && (selectionRect != null) && area.intersects(selectionRect)) {
newSelection.addAll(findAllGroupedComponents(component));
}
}
}
selectionRect = null;
@@ -864,6 +884,19 @@ public class Presenter implements IPlugInPort {
}
}
@Override
public void setLayerLocked(int layerZOrder, boolean locked) {
if (locked) {
currentProject.getLockedLayers().add(layerZOrder);
} else {
currentProject.getLockedLayers().remove(layerZOrder);
}
updateSelection(ComponentSelection.EMPTY_SELECTION);
messageDispatcher.dispatchMessage(EventType.REPAINT);
messageDispatcher.dispatchMessage(EventType.LAYER_STATE_CHANGED, currentProject
.getLockedLayers());
}
/**
* Updates the selection with the specified {@link ComponentSelection}.
* Also, updates control point map with all components that are stuck to the
@@ -945,6 +978,8 @@ public class Presenter implements IPlugInPort {
Area componentArea = drawingManager.getComponentArea(component);
if (componentArea != null) {
area.add(componentArea);
} else {
LOG.warn("No area found for: " + component.getName());
}
}
double width = area.getBounds2D().getWidth();
@@ -1081,6 +1116,22 @@ public class Presenter implements IPlugInPort {
}
}
private Set<IDIYComponent<?>> getLockedComponents() {
lockedComponents.clear();
for (IDIYComponent<?> component : currentProject.getComponents()) {
if (isComponentLocked(component)) {
lockedComponents.add(component);
}
}
return lockedComponents;
}
private boolean isComponentLocked(IDIYComponent<?> component) {
ComponentType componentType = componentTypeMap.get(component.getClass().getName());
return currentProject.getLockedLayers().contains(
(int) Math.round(componentType.getZOrder()));
}
/**
* Scales point from display base to actual base.
*