Show and hide each individual layer

This commit is contained in:
bancika
2017-04-21 11:55:40 +02:00
parent f6ad118044
commit e342ed1c2c
6 changed files with 93 additions and 13 deletions
@@ -72,6 +72,11 @@ public enum EventType {
* layers. All layers not included are considered unlocked. * layers. All layers not included are considered unlocked.
*/ */
LAYER_STATE_CHANGED, LAYER_STATE_CHANGED,
/**
* Called when a layer visibility is changed. The first parameter is a set of indices of hidden
* layers. All layers not included are considered visible.
*/
LAYER_VISIBILITY_CHANGED,
/** /**
* Called to update the status message. New status message is passed as a first parameter. * Called to update the status message. New status message is passed as a first parameter.
*/ */
@@ -254,6 +254,15 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
*/ */
void setLayerLocked(int layerZOrder, boolean locked); void setLayerLocked(int layerZOrder, boolean locked);
/**
* Shows or hides the specified layer. All components within +- 0.5 range will be affected by
* the change as well.
*
* @param layerZOrder
* @param visible
*/
void setLayerVisibility(int layerZOrder, boolean visible);
/** /**
* @return selection size expressed in both inches or centimeters, respectively * @return selection size expressed in both inches or centimeters, respectively
*/ */
@@ -45,12 +45,14 @@ public class Project implements Serializable {
private List<IDIYComponent<?>> components; private List<IDIYComponent<?>> components;
private Set<Set<IDIYComponent<?>>> groups; private Set<Set<IDIYComponent<?>>> groups;
private Set<Integer> lockedLayers; private Set<Integer> lockedLayers;
private Set<Integer> hiddenLayers;
private Font font = DEFAULT_FONT; private Font font = DEFAULT_FONT;
public Project() { public Project() {
components = new ArrayList<IDIYComponent<?>>(); components = new ArrayList<IDIYComponent<?>>();
groups = new HashSet<Set<IDIYComponent<?>>>(); groups = new HashSet<Set<IDIYComponent<?>>>();
lockedLayers = new HashSet<Integer>(); lockedLayers = new HashSet<Integer>();
hiddenLayers = new HashSet<Integer>();
title = DEFAULT_TITLE; title = DEFAULT_TITLE;
author = System.getProperty("user.name"); author = System.getProperty("user.name");
width = DEFAULT_WIDTH; width = DEFAULT_WIDTH;
@@ -135,6 +137,12 @@ public class Project implements Serializable {
return lockedLayers; return lockedLayers;
} }
public Set<Integer> getHiddenLayers() {
if (hiddenLayers == null)
hiddenLayers = new HashSet<Integer>();
return hiddenLayers;
}
public VersionNumber getFileVersion() { public VersionNumber getFileVersion() {
return fileVersion; return fileVersion;
} }
@@ -261,6 +269,7 @@ public class Project implements Serializable {
project.setHeight(this.getHeight()); project.setHeight(this.getHeight());
project.setWidth(this.getWidth()); project.setWidth(this.getWidth());
project.getLockedLayers().addAll(this.getLockedLayers()); project.getLockedLayers().addAll(this.getLockedLayers());
project.getHiddenLayers().addAll(this.getHiddenLayers());
Map<IDIYComponent<?>, IDIYComponent<?>> cloneMap = new HashMap<IDIYComponent<?>, IDIYComponent<?>>(); Map<IDIYComponent<?>, IDIYComponent<?>> cloneMap = new HashMap<IDIYComponent<?>, IDIYComponent<?>>();
@@ -189,7 +189,7 @@ public class Presenter implements IPlugInPort {
return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
} }
for (IDIYComponent<?> component : currentProject.getComponents()) { for (IDIYComponent<?> component : currentProject.getComponents()) {
if (!isComponentLocked(component)) { if (!isComponentLocked(component) && isComponentVisible(component)) {
Area area = drawingManager.getComponentArea(component); Area area = drawingManager.getComponentArea(component);
if (area != null && area.contains(scaledPoint)) { if (area != null && area.contains(scaledPoint)) {
return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
@@ -219,6 +219,7 @@ public class Presenter implements IPlugInPort {
messageDispatcher.dispatchMessage(EventType.PROJECT_LOADED, project, freshStart); messageDispatcher.dispatchMessage(EventType.PROJECT_LOADED, project, freshStart);
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
messageDispatcher.dispatchMessage(EventType.LAYER_STATE_CHANGED, currentProject.getLockedLayers()); messageDispatcher.dispatchMessage(EventType.LAYER_STATE_CHANGED, currentProject.getLockedLayers());
messageDispatcher.dispatchMessage(EventType.LAYER_VISIBILITY_CHANGED, currentProject.getHiddenLayers());
} }
@Override @Override
@@ -374,9 +375,16 @@ public class Presenter implements IPlugInPort {
return autoCreators; return autoCreators;
} }
@SuppressWarnings({"unchecked"})
private boolean isComponentVisible(IDIYComponent<?> component) {
ComponentType componentType =
ComponentProcessor.getInstance().extractComponentTypeFrom(
(Class<? extends IDIYComponent<?>>) component.getClass());
return !currentProject.getHiddenLayers().contains((int) Math.round(componentType.getZOrder()));
}
@Override @Override
public void draw(Graphics2D g2d, Set<DrawOption> drawOptions, IComponentFiler filter) { public void draw(Graphics2D g2d, Set<DrawOption> drawOptions, final IComponentFiler filter) {
if (currentProject == null) { if (currentProject == null) {
return; return;
} }
@@ -387,6 +395,16 @@ public class Presenter implements IPlugInPort {
groupedComponents.add(component); groupedComponents.add(component);
} }
} }
// Concatenate the specified filter with our own filter that removes hidden layers
IComponentFiler newFiler = new IComponentFiler() {
@Override
public boolean testComponent(IDIYComponent<?> component) {
return (filter == null || filter.testComponent(component)) && isComponentVisible(component);
}
};
// Don't draw the component in the slot if both control points // Don't draw the component in the slot if both control points
// match. // match.
List<IDIYComponent<?>> componentSlotToDraw; List<IDIYComponent<?>> componentSlotToDraw;
@@ -402,7 +420,7 @@ public class Presenter implements IPlugInPort {
g2d, g2d,
currentProject, currentProject,
drawOptions, drawOptions,
filter, newFiler,
selectionRect, selectionRect,
selectedComponents, selectedComponents,
getLockedComponents(), getLockedComponents(),
@@ -433,7 +451,8 @@ public class Presenter implements IPlugInPort {
List<IDIYComponent<?>> components = drawingManager.findComponentsAt(point, currentProject); List<IDIYComponent<?>> components = drawingManager.findComponentsAt(point, currentProject);
Iterator<IDIYComponent<?>> iterator = components.iterator(); Iterator<IDIYComponent<?>> iterator = components.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
if (isComponentLocked(iterator.next())) { IDIYComponent<?> component = iterator.next();
if (isComponentLocked(component) || !isComponentVisible(component)) {
iterator.remove(); iterator.remove();
} }
} }
@@ -530,8 +549,8 @@ public class Presenter implements IPlugInPort {
List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>(); List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>();
for (IDIYComponent<?> component : componentSlot) { for (IDIYComponent<?> component : componentSlot) {
addComponent(component, true); addComponent(component, true);
// Select the new component if it's not locked. // Select the new component if it's not locked and invisible.
if (!isComponentLocked(component)) { if (!isComponentLocked(component) && isComponentVisible(component)) {
newSelection.add(component); newSelection.add(component);
} }
} }
@@ -933,7 +952,7 @@ public class Presenter implements IPlugInPort {
// Do not process a control point if it's already in the map and // Do not process a control point if it's already in the map and
// if it's locked. // if it's locked.
if ((!controlPointMap.containsKey(component) || !controlPointMap.get(component).contains(i)) if ((!controlPointMap.containsKey(component) || !controlPointMap.get(component).contains(i))
&& !isComponentLocked(component)) { && !isComponentLocked(component) && isComponentVisible(component)) {
if (component.isControlPointSticky(i)) { if (component.isControlPointSticky(i)) {
boolean componentMatches = false; boolean componentMatches = false;
for (Map.Entry<IDIYComponent<?>, Set<Integer>> entry : controlPointMap.entrySet()) { for (Map.Entry<IDIYComponent<?>, Set<Integer>> entry : controlPointMap.entrySet()) {
@@ -1315,7 +1334,7 @@ public class Presenter implements IPlugInPort {
} }
List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>(); List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>();
for (IDIYComponent<?> component : currentProject.getComponents()) { for (IDIYComponent<?> component : currentProject.getComponents()) {
if (!isComponentLocked(component)) { if (!isComponentLocked(component) && isComponentVisible(component)) {
Area area = drawingManager.getComponentArea(component); Area area = drawingManager.getComponentArea(component);
if ((area != null) && (selectionRect != null) && area.intersects(selectionRect)) { if ((area != null) && (selectionRect != null) && area.intersects(selectionRect)) {
newSelection.addAll(findAllGroupedComponents(component)); newSelection.addAll(findAllGroupedComponents(component));
@@ -1438,6 +1457,19 @@ public class Presenter implements IPlugInPort {
messageDispatcher.dispatchMessage(EventType.LAYER_STATE_CHANGED, currentProject.getLockedLayers()); messageDispatcher.dispatchMessage(EventType.LAYER_STATE_CHANGED, currentProject.getLockedLayers());
} }
@Override
public void setLayerVisibility(int layerZOrder, boolean visible) {
LOG.info(String.format("setLayerVisibility(%s, %s)", layerZOrder, visible));
if (visible) {
currentProject.getHiddenLayers().remove(layerZOrder);
} else {
currentProject.getHiddenLayers().add(layerZOrder);
}
updateSelection(EMPTY_SELECTION);
messageDispatcher.dispatchMessage(EventType.REPAINT);
messageDispatcher.dispatchMessage(EventType.LAYER_VISIBILITY_CHANGED, currentProject.getHiddenLayers());
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void sendSelectionToBack() { public void sendSelectionToBack() {
@@ -22,10 +22,12 @@ public class LayersMenuPlugin implements IPlugIn {
private IPlugInPort plugInPort; private IPlugInPort plugInPort;
private Map<Layer, Action> lockActionMap; private Map<Layer, Action> lockActionMap;
private Map<Layer, Action> visibleActionMap;
private Map<Integer, Action> selectAllActionMap; private Map<Integer, Action> selectAllActionMap;
public LayersMenuPlugin(ISwingUI swingUI) { public LayersMenuPlugin(ISwingUI swingUI) {
lockActionMap = new HashMap<Layer, Action>(); lockActionMap = new HashMap<Layer, Action>();
visibleActionMap = new HashMap<Layer, Action>();
selectAllActionMap = new HashMap<Integer, Action>(); selectAllActionMap = new HashMap<Integer, Action>();
for (Layer layer : Layer.values()) { for (Layer layer : Layer.values()) {
final int zOrder = layer.getZOrder(); final int zOrder = layer.getZOrder();
@@ -36,12 +38,25 @@ public class LayersMenuPlugin implements IPlugIn {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
LayersMenuPlugin.this.plugInPort.setLayerLocked(zOrder, (Boolean) getValue(Action.SELECTED_KEY)); LayersMenuPlugin.this.plugInPort.setLayerLocked(zOrder, (Boolean) getValue(Action.SELECTED_KEY));
selectAllActionMap.get(zOrder).setEnabled(!(Boolean) getValue(Action.SELECTED_KEY)); // selectAllActionMap.get(zOrder).setEnabled(!(Boolean) getValue(Action.SELECTED_KEY));
} }
}; };
lockAction.putValue(IView.CHECK_BOX_MENU_ITEM, true); lockAction.putValue(IView.CHECK_BOX_MENU_ITEM, true);
lockActionMap.put(layer, lockAction); lockActionMap.put(layer, lockAction);
AbstractAction visibleAction = new AbstractAction("Visible") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
LayersMenuPlugin.this.plugInPort.setLayerVisibility(zOrder, getValue(Action.SELECTED_KEY) == null ? true : (Boolean) getValue(Action.SELECTED_KEY));
// selectAllActionMap.get(zOrder).setEnabled(!(Boolean) getValue(Action.SELECTED_KEY));
}
};
visibleAction.putValue(IView.CHECK_BOX_MENU_ITEM, true);
visibleActionMap.put(layer, visibleAction);
AbstractAction selectAllAction = new AbstractAction("Select All") { AbstractAction selectAllAction = new AbstractAction("Select All") {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -54,6 +69,7 @@ public class LayersMenuPlugin implements IPlugIn {
selectAllActionMap.put(zOrder, selectAllAction); selectAllActionMap.put(zOrder, selectAllAction);
swingUI.injectSubmenu(layer.title, null, LOCK_LAYERS_TITLE); swingUI.injectSubmenu(layer.title, null, LOCK_LAYERS_TITLE);
swingUI.injectMenuAction(visibleAction, layer.title);
swingUI.injectMenuAction(lockAction, layer.title); swingUI.injectMenuAction(lockAction, layer.title);
swingUI.injectMenuAction(selectAllAction, layer.title); swingUI.injectMenuAction(selectAllAction, layer.title);
} }
@@ -66,7 +82,7 @@ public class LayersMenuPlugin implements IPlugIn {
@Override @Override
public EnumSet<EventType> getSubscribedEventTypes() { public EnumSet<EventType> getSubscribedEventTypes() {
return EnumSet.of(EventType.LAYER_STATE_CHANGED); return EnumSet.of(EventType.LAYER_STATE_CHANGED, EventType.LAYER_VISIBILITY_CHANGED);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -77,6 +93,11 @@ public class LayersMenuPlugin implements IPlugIn {
for (Layer layer : Layer.values()) { for (Layer layer : Layer.values()) {
lockActionMap.get(layer).putValue(Action.SELECTED_KEY, lockedLayers.contains(layer.getZOrder())); lockActionMap.get(layer).putValue(Action.SELECTED_KEY, lockedLayers.contains(layer.getZOrder()));
} }
} else if (eventType == EventType.LAYER_VISIBILITY_CHANGED) {
Set<Integer> hiddenLayers = (Set<Integer>) params[0];
for (Layer layer : Layer.values()) {
visibleActionMap.get(layer).putValue(Action.SELECTED_KEY, !hiddenLayers.contains(layer.getZOrder()));
}
} }
} }
+4
View File
@@ -1702,6 +1702,10 @@
<releaseDate>2017-04-20 20:00:00.000 CET</releaseDate> <releaseDate>2017-04-20 20:00:00.000 CET</releaseDate>
<name></name> <name></name>
<changes> <changes>
<org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Show and hide each individual layer</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change> <org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType> <changeType>NEW_FEATURE</changeType>
<description>Red ticks on both rulers mark selection bounds, blue tick tracks cursor position</description> <description>Red ticks on both rulers mark selection bounds, blue tick tracks cursor position</description>