Skip to content

Commit 59ce642

Browse files
authored
Merge pull request #5912 from kwvanderlinde/feature/5324-wall-mass-selection
Multiple wall selection
2 parents e0f074a + 1f8ef63 commit 59ce642

File tree

4 files changed

+329
-88
lines changed

4 files changed

+329
-88
lines changed

src/main/java/net/rptools/maptool/client/swing/walls/WallConfigurationController.java

Lines changed: 112 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,113 @@
1414
*/
1515
package net.rptools.maptool.client.swing.walls;
1616

17-
import com.google.common.collect.ImmutableMap;
18-
import com.google.common.collect.Maps;
1917
import java.beans.PropertyChangeEvent;
2018
import java.beans.PropertyChangeListener;
2119
import java.util.EnumMap;
20+
import java.util.Map;
21+
import java.util.Objects;
2222
import javax.annotation.Nonnull;
23+
import javax.annotation.Nullable;
2324
import javax.swing.JComboBox;
25+
import net.rptools.lib.CollectionUtil;
2426
import net.rptools.maptool.model.topology.VisibilityType;
2527
import net.rptools.maptool.model.topology.Wall;
2628

2729
public class WallConfigurationController {
30+
/**
31+
* Like Wall.Data, but mutable, observable, and nullable (in case of multiple selected walls not
32+
* agreeing).
33+
*/
34+
public static final class WallData {
35+
36+
private final @Nullable Wall.Direction direction;
37+
private final @Nullable Wall.MovementDirectionModifier movementModifier;
38+
// DO NOT MODIFY `modifiers`!
39+
private final EnumMap<VisibilityType, Wall.DirectionModifier> modifiers;
40+
41+
public WallData(
42+
@Nullable Wall.Direction direction,
43+
@Nullable Wall.MovementDirectionModifier movementModifier,
44+
Map<VisibilityType, Wall.DirectionModifier> modifiers) {
45+
this.direction = direction;
46+
this.movementModifier = movementModifier;
47+
this.modifiers = new EnumMap<>(VisibilityType.class);
48+
this.modifiers.putAll(modifiers);
49+
}
50+
51+
public WallData(WallData other) {
52+
this(other.direction, other.movementModifier, other.modifiers);
53+
}
54+
55+
public WallData(Wall.Data data) {
56+
this(
57+
data.direction(),
58+
data.movementModifier(),
59+
CollectionUtil.newFilledEnumMap(VisibilityType.class, data::directionModifier));
60+
}
61+
62+
@Override
63+
public boolean equals(Object obj) {
64+
if (!(obj instanceof WallData other)) {
65+
return false;
66+
}
67+
68+
return this.direction == other.direction
69+
&& this.movementModifier == other.movementModifier
70+
&& this.modifiers.equals(other.modifiers);
71+
}
72+
73+
public @Nullable Wall.Direction direction() {
74+
return direction;
75+
}
76+
77+
public WallData withDirection(@Nullable Wall.Direction direction) {
78+
return new WallData(direction, this.movementModifier, this.modifiers);
79+
}
80+
81+
public @Nullable Wall.MovementDirectionModifier movementModifier() {
82+
return movementModifier;
83+
}
84+
85+
public WallData withMovementModifier(
86+
@Nullable Wall.MovementDirectionModifier movementModifier) {
87+
return new WallData(this.direction, movementModifier, this.modifiers);
88+
}
89+
90+
public @Nullable Wall.DirectionModifier directionModifier(VisibilityType visibilityType) {
91+
return this.modifiers.get(visibilityType);
92+
}
93+
94+
public WallData withDirectionModifier(
95+
VisibilityType visibilityType, @Nullable Wall.DirectionModifier modifier) {
96+
var newModifiers = new EnumMap<>(this.modifiers);
97+
if (modifier == null) {
98+
newModifiers.remove(visibilityType);
99+
} else {
100+
newModifiers.put(visibilityType, modifier);
101+
}
102+
return new WallData(this.direction, this.movementModifier, newModifiers);
103+
}
104+
105+
public Wall.Data toWallData() {
106+
return toWallData(new Wall.Data());
107+
}
108+
109+
public Wall.Data toWallData(Wall.Data original) {
110+
return new Wall.Data(
111+
Objects.requireNonNullElse(direction, original.direction()),
112+
Objects.requireNonNullElse(movementModifier, original.movementModifier()),
113+
CollectionUtil.newFilledEnumMap(
114+
VisibilityType.class,
115+
type ->
116+
Objects.requireNonNullElseGet(
117+
modifiers.get(type), () -> original.directionModifier(type))));
118+
}
119+
}
120+
28121
private final WallConfigurationView view;
29122
private final PropertyChangeListener changeListener;
30-
private @Nonnull Wall.Data wallData = new Wall.Data();
123+
private @Nonnull WallData wallData = new WallData(new Wall.Data());
31124

32125
public WallConfigurationController(PropertyChangeListener changeListener) {
33126
this.view = new WallConfigurationView();
@@ -38,7 +131,7 @@ public WallConfigurationController(PropertyChangeListener changeListener) {
38131
e -> {
39132
var newDirection = directionSelect.getItemAt(directionSelect.getSelectedIndex());
40133
if (newDirection != null) {
41-
updateWall(newDirection, wallData.movementModifier(), wallData.modifiers());
134+
updateWall(wallData.withDirection(newDirection));
42135
}
43136
});
44137

@@ -48,7 +141,7 @@ public WallConfigurationController(PropertyChangeListener changeListener) {
48141
var modifier =
49142
movementModifierSelect.getItemAt(movementModifierSelect.getSelectedIndex());
50143
if (modifier != null) {
51-
updateWall(wallData.direction(), modifier, wallData.modifiers());
144+
updateWall(wallData.withMovementModifier(modifier));
52145
}
53146
});
54147

@@ -58,34 +151,19 @@ public WallConfigurationController(PropertyChangeListener changeListener) {
58151
e -> {
59152
var modifier = input.getItemAt(input.getSelectedIndex());
60153
if (modifier != null) {
61-
var newModifiers =
62-
new EnumMap<VisibilityType, Wall.DirectionModifier>(VisibilityType.class);
63-
newModifiers.putAll(wallData.modifiers());
64-
newModifiers.put(visibilityType, modifier);
65-
66-
updateWall(
67-
wallData.direction(),
68-
wallData.movementModifier(),
69-
Maps.immutableEnumMap(newModifiers));
154+
updateWall(wallData.withDirectionModifier(visibilityType, modifier));
70155
}
71156
});
72157
}
73158
}
74159

75-
private void updateWall(
76-
Wall.Direction direction,
77-
Wall.MovementDirectionModifier movementModifier,
78-
ImmutableMap<VisibilityType, Wall.DirectionModifier> modifiers) {
79-
var newWallData = new Wall.Data(direction, movementModifier, modifiers);
80-
81-
if (wallData.equals(newWallData)) {
82-
return;
160+
private void updateWall(WallData newWallData) {
161+
if (!wallData.equals(newWallData)) {
162+
var oldWallData = wallData;
163+
wallData = newWallData;
164+
changeListener.propertyChange(
165+
new PropertyChangeEvent(this, "wallData", oldWallData, wallData));
83166
}
84-
85-
var oldWallData = wallData;
86-
wallData = newWallData;
87-
88-
changeListener.propertyChange(new PropertyChangeEvent(this, "wallData", oldWallData, wallData));
89167
}
90168

91169
public WallConfigurationView getView() {
@@ -101,7 +179,11 @@ private JComboBox<Wall.DirectionModifier> getModifierInput(VisibilityType visibi
101179
}
102180

103181
public void bind(@Nonnull Wall.Data model) {
104-
this.wallData = model;
182+
bind(new WallData(model));
183+
}
184+
185+
public void bind(@Nonnull WallData model) {
186+
this.wallData = new WallData(model);
105187

106188
this.view.getDirectionSelect().setSelectedItem(this.wallData.direction());
107189
this.view.getMovementModifier().setSelectedItem(this.wallData.movementModifier());
@@ -111,7 +193,7 @@ public void bind(@Nonnull Wall.Data model) {
111193
}
112194
}
113195

114-
public @Nonnull Wall.Data getModel() {
115-
return wallData;
196+
public @Nonnull WallData getModel() {
197+
return new WallData(wallData);
116198
}
117199
}

0 commit comments

Comments
 (0)