Skip to content

Commit

Permalink
Area Viewer: Add new layer "Impeded Door Cells"
Browse files Browse the repository at this point in the history
Experimental implementation: may have some performance issues if many
cell blocks are defined.
  • Loading branch information
Argent77 committed Jul 28, 2023
1 parent fe3a1d9 commit 5a52754
Show file tree
Hide file tree
Showing 18 changed files with 548 additions and 97 deletions.
26 changes: 25 additions & 1 deletion src/org/infinity/gui/layeritem/AbstractLayerItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,35 @@ public enum ItemState {
private final Vector<ActionListener> actionListener = new Vector<>();
private final Vector<LayerItemListener> itemStateListener = new Vector<>();
private final Viewable viewable;
private final Point center;
private final int id;

private Object objData;
private ItemState itemState;
private final Point center;

/**
* Initialize object with a associated viewable object and message for both info box and quick info.
* The item is automatically associated with the primary sublayer.
*
* @param viewable Associated Viewable object
* @param tooltip A short text message shown as tooltip or menu item text
*/
public AbstractLayerItem(Viewable viewable, String tooltip) {
this(viewable, tooltip, 0);
}

/**
* Initialize object with a associated viewable object and message for both info box and quick info.
*
* @param viewable Associated Viewable object
* @param tooltip A short text message shown as tooltip or menu item text
* @param id Identifier that associates this item with a specific sublayer.
*/
public AbstractLayerItem(Viewable viewable, String tooltip, int id) {
this.viewable = viewable;
this.itemState = ItemState.NORMAL;
this.center = new Point();
this.id = id;
if (viewable instanceof StructEntry) {
setToolTipText(((StructEntry) viewable).getName() + ": " + tooltip);
} else {
Expand Down Expand Up @@ -115,6 +130,15 @@ public ItemState getItemState() {
return itemState;
}

/**
* Returns the sublayer identifier associated with this layer item.
*
* @return Sublayer iIdentifier for this layer item.
*/
public int getId() {
return id;
}

/**
* Attaches a custom data object to this layer item.
*
Expand Down
27 changes: 26 additions & 1 deletion src/org/infinity/gui/layeritem/IconLayerItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ public class IconLayerItem extends AbstractLayerItem implements LayerItemListene
* @param message An arbitrary text message
*/
public IconLayerItem(Viewable viewable, String message) {
this(viewable, message, 0);
}

/**
* Initialize object with an associated Viewable and an additional text message.
*
* @param viewable Associated Viewable object
* @param message An arbitrary text message
* @param id Identifier that associates this item with a specific sublayer.
*/
public IconLayerItem(Viewable viewable, String message, int id) {
this(viewable, message, null, null);
}

Expand All @@ -58,7 +69,21 @@ public IconLayerItem(Viewable viewable, String message) {
* @param center Logical center position within the icon
*/
public IconLayerItem(Viewable viewable, String tooltip, Image image, Point center) {
super(viewable, tooltip);
this(viewable, tooltip, 0, image, center);
}

/**
* Initialize object with an associated Viewable, an additional text message, an image for the visual representation
* and a locical center position within the icon.
*
* @param viewable Associated Viewable object
* @param tooltip A short text message shown as tooltip or menu item text
* @param id Identifier that associates this item with a specific sublayer.
* @param image The image to display
* @param center Logical center position within the icon
*/
public IconLayerItem(Viewable viewable, String tooltip, int id, Image image, Point center) {
super(viewable, tooltip, id);
setLayout(new BorderLayout());
// preparing icon
rcCanvas = new FrameCanvas(this);
Expand Down
13 changes: 13 additions & 0 deletions src/org/infinity/gui/layeritem/ShapedLayerItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@ public class ShapedLayerItem extends AbstractLayerItem implements LayerItemListe
* @param shape The shape to display
*/
public ShapedLayerItem(Viewable viewable, String tooltip, Shape shape) {
this(viewable, tooltip, 0, shape);
}

/**
* Initialize object with an associated Viewable, an additional text message and a shape for the visual
* representation.
*
* @param viewable Associated Viewable object
* @param tooltip A short text message shown as tooltip or menu item text
* @param id Identifier that associates this item with a specific sublayer.
* @param shape The shape to display
*/
public ShapedLayerItem(Viewable viewable, String tooltip, int id, Shape shape) {
super(viewable, tooltip);
setLayout(new BorderLayout());
label = new ShapeLabel(this);
Expand Down
18 changes: 12 additions & 6 deletions src/org/infinity/resource/are/viewer/AreaViewer.java
Original file line number Diff line number Diff line change
Expand Up @@ -1640,7 +1640,7 @@ private void updateRegionTargets() {
JCheckBox cb = cbLayers[LayerManager.getLayerTypeIndex(LayerType.REGION)];
cbLayerRegionTarget.setEnabled(cb.isSelected() && cb.isEnabled());
boolean state = cbLayerRegionTarget.isEnabled() && cbLayerRegionTarget.isSelected();
layer.setIconLayerEnabled(state);
layer.setLayerEnabled(LayerRegion.LAYER_ICONS_TARGET, state);
} else {
cbLayerRegionTarget.setEnabled(false);
}
Expand All @@ -1659,7 +1659,7 @@ private void updateContainerTargets() {
JCheckBox cb = cbLayers[LayerManager.getLayerTypeIndex(LayerType.CONTAINER)];
cbLayerContainerTarget.setEnabled(cb.isSelected() && cb.isEnabled());
boolean state = cbLayerContainerTarget.isEnabled() && cbLayerContainerTarget.isSelected();
layer.setIconLayerEnabled(state);
layer.setLayerEnabled(LayerContainer.LAYER_ICONS_TARGET, state);
} else {
cbLayerContainerTarget.setEnabled(false);
}
Expand All @@ -1678,7 +1678,7 @@ private void updateDoorTargets() {
JCheckBox cb = cbLayers[LayerManager.getLayerTypeIndex(LayerType.DOOR)];
cbLayerDoorTarget.setEnabled(cb.isSelected() && cb.isEnabled());
boolean state = cbLayerDoorTarget.isEnabled() && cbLayerDoorTarget.isSelected();
layer.setIconLayerEnabled(state);
layer.setLayerEnabled(LayerDoor.LAYER_ICONS_TARGET, state);
} else {
cbLayerDoorTarget.setEnabled(false);
}
Expand Down Expand Up @@ -1840,6 +1840,7 @@ private void addLayerItem(LayerStackingType layer, LayerObject object) {
type = ViewerConstants.LAYER_ITEM_POLY;
break;
case DOOR:
case DOOR_CELLS:
type = ViewerConstants.DOOR_ANY | ViewerConstants.LAYER_ITEM_POLY;
break;
case CONTAINER_TARGET:
Expand Down Expand Up @@ -1900,6 +1901,7 @@ private void removeLayerItem(LayerStackingType layer, LayerObject object) {
type = ViewerConstants.LAYER_ITEM_POLY;
break;
case DOOR:
case DOOR_CELLS:
type = ViewerConstants.DOOR_ANY | ViewerConstants.LAYER_ITEM_POLY;
break;
case CONTAINER_TARGET:
Expand Down Expand Up @@ -1948,6 +1950,7 @@ private void orderLayerItems() {
type = ViewerConstants.LAYER_ITEM_POLY;
break;
case DOOR:
case DOOR_CELLS:
type = ViewerConstants.DOOR_ANY | ViewerConstants.LAYER_ITEM_POLY;
break;
case CONTAINER_TARGET:
Expand Down Expand Up @@ -2136,9 +2139,12 @@ private void applySettings() {
// applying animation active override settings
((LayerAnimation) layerManager.getLayer(LayerType.ANIMATION))
.setRealAnimationActiveIgnored(Settings.OverrideAnimVisibility);
((LayerContainer) layerManager.getLayer(LayerType.CONTAINER)).setIconLayerEnabled(Settings.ShowContainerTargets);
((LayerDoor) layerManager.getLayer(LayerType.DOOR)).setIconLayerEnabled(Settings.ShowDoorTargets);
((LayerRegion) layerManager.getLayer(LayerType.REGION)).setIconLayerEnabled(Settings.ShowRegionTargets);
((LayerContainer) layerManager.getLayer(LayerType.CONTAINER)).setLayerEnabled(LayerContainer.LAYER_ICONS_TARGET,
Settings.ShowContainerTargets);
((LayerDoor) layerManager.getLayer(LayerType.DOOR)).setLayerEnabled(LayerDoor.LAYER_ICONS_TARGET,
Settings.ShowDoorTargets);
((LayerRegion) layerManager.getLayer(LayerType.REGION)).setLayerEnabled(LayerRegion.LAYER_ICONS_TARGET,
Settings.ShowRegionTargets);

// applying interpolation settings to animations
switch (Settings.InterpolationAnim) {
Expand Down
57 changes: 57 additions & 0 deletions src/org/infinity/resource/are/viewer/BasicCompositeLayer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Near Infinity - An Infinity Engine Browser and Editor
// Copyright (C) 2001 Jon Olav Hauglid
// See LICENSE.txt for license information

package org.infinity.resource.are.viewer;

import java.util.HashMap;

import org.infinity.gui.layeritem.AbstractLayerItem;
import org.infinity.resource.AbstractStruct;
import org.infinity.resource.are.viewer.ViewerConstants.LayerType;

/**
* Specialized base class for layer-specific managers that consists of multiple sublayers.
*
* @param <E> Type of the layer item in the manager
* @param <R> Type of the resource that contains layer items
*/
public abstract class BasicCompositeLayer<E extends LayerObject, R extends AbstractStruct> extends BasicLayer<E, R> {
/** Predefined identifier for use with the primary sublayer. */
public static final int LAYER_PRIMARY = 0;

private final HashMap<Integer, Boolean> layerEnabled = new HashMap<>();

public BasicCompositeLayer(R parent, LayerType type, AreaViewer viewer) {
super(parent, type, viewer);
setLayerEnabled(LAYER_PRIMARY, true);
}

public boolean isLayerVisible(int id) {
return isLayerVisible() && layerEnabled.getOrDefault(id, false);
}

@Override
public void setLayerVisible(boolean visible) {
setVisibilityState(visible);

getLayerObjects().stream().forEach(obj -> {
AbstractLayerItem[] items = obj.getLayerItems();
for (final AbstractLayerItem item : items) {
final int id = item.getId();
item.setVisible(isLayerVisible(id) && isLayerEnabled(id));
}
});
}

public boolean isLayerEnabled(int id) {
return layerEnabled.getOrDefault(id, false);
}

public void setLayerEnabled(int id, boolean enable) {
if (isLayerEnabled(id) != enable) {
layerEnabled.put(id, enable);
setLayerVisible(isLayerVisible(LAYER_PRIMARY) || isLayerVisible(id));
}
}
}
68 changes: 0 additions & 68 deletions src/org/infinity/resource/are/viewer/BasicTargetLayer.java

This file was deleted.

5 changes: 4 additions & 1 deletion src/org/infinity/resource/are/viewer/LayerContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
/**
* Manages container layer objects.
*/
public class LayerContainer extends BasicTargetLayer<LayerObjectContainer, AreResource> {
public class LayerContainer extends BasicCompositeLayer<LayerObjectContainer, AreResource> {
/** Identifier for the target icons sublayer. */
public static final int LAYER_ICONS_TARGET = 1;

private static final String AVAILABLE_FMT = "Containers: %d";

public LayerContainer(AreResource are, AreaViewer viewer) {
Expand Down
18 changes: 14 additions & 4 deletions src/org/infinity/resource/are/viewer/LayerDoor.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
/**
* Manages door layer objects.
*/
public class LayerDoor extends BasicTargetLayer<LayerObjectDoor, AreResource> {
public class LayerDoor extends BasicCompositeLayer<LayerObjectDoor, AreResource> {
/** Identifier for the target icons sublayer. */
public static final int LAYER_ICONS_TARGET = 1;

private static final String AVAILABLE_FMT = "Doors: %d";

private boolean doorClosed;
Expand Down Expand Up @@ -42,17 +45,24 @@ public void setLayerVisible(boolean visible) {
getLayerObjects().stream().forEach(obj -> {
AbstractLayerItem[] items = obj.getLayerItems(ViewerConstants.DOOR_OPEN | ViewerConstants.LAYER_ITEM_POLY);
for (final AbstractLayerItem item : items) {
item.setVisible(isPolyLayerVisible() && isPolyLayerEnabled() && !doorClosed);
item.setVisible(isLayerVisible(LAYER_PRIMARY) && isLayerEnabled(LAYER_PRIMARY) && !doorClosed);
}

items = obj.getLayerItems(ViewerConstants.DOOR_CLOSED | ViewerConstants.LAYER_ITEM_POLY);
for (final AbstractLayerItem item : items) {
item.setVisible(isPolyLayerVisible() && isPolyLayerEnabled() && doorClosed);
item.setVisible(isLayerVisible(LAYER_PRIMARY) && isLayerEnabled(LAYER_PRIMARY) && doorClosed);
}

items = obj.getLayerItems(ViewerConstants.LAYER_ITEM_ICON);
for (final AbstractLayerItem item : items) {
item.setVisible(isIconsLayerVisible() && isIconsLayerEnabled());
switch (item.getId()) {
case LAYER_ICONS_TARGET:
item.setVisible(isLayerVisible(LAYER_ICONS_TARGET) && isLayerEnabled(LAYER_ICONS_TARGET));
break;
default:
item.setVisible(false);
System.out.println("Unknown layer id: " + item.getId());
}
}
});
}
Expand Down
Loading

0 comments on commit 5a52754

Please sign in to comment.