Gridarta Editor
SelectionTool.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2015 The Gridarta Developers.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package net.sf.gridarta.gui.panel.tools;
21 
22 import java.awt.Component;
23 import java.awt.Container;
24 import java.awt.GridBagConstraints;
25 import java.awt.GridBagLayout;
26 import java.awt.Point;
27 import java.awt.event.InputEvent;
28 import javax.swing.JComboBox;
29 import javax.swing.JPanel;
43 import net.sf.japi.swing.action.ActionBuilder;
44 import net.sf.japi.swing.action.ActionBuilderFactory;
45 import net.sf.japi.swing.action.ActionMethod;
46 import net.sf.japi.swing.action.ToggleAction;
47 import org.jetbrains.annotations.NotNull;
48 import org.jetbrains.annotations.Nullable;
49 
54 public class SelectionTool<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> extends BasicAbstractTool<G, A, R> {
55 
59  private static final int MODE_AUTO = 0;
60 
64  private static final int MODE_TOPMOST = 1;
65 
69  private static final int MODE_ABOVE_FLOOR = 2;
70 
74  private static final int MODE_BELOW_FLOOR = 3;
75 
79  private static final int MODE_BOTTOMMOST = 4;
80 
84  @NotNull
85  private static final ActionBuilder ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder("net.sf.gridarta.gui.panel.tools");
86 
90  @NotNull
91  private final ToggleAction autoFillAction = (ToggleAction) ACTION_BUILDER.createToggle(true, "selectionToolAutoFill", this);
92 
96  @NotNull
97  private final JComboBox<?> modeComboBox = createModeComboBox();
98 
102  @NotNull
104 
108  @NotNull
110 
114  private boolean selectionToolAutoFill;
115 
121  public SelectionTool(@NotNull final ObjectChooser<G, A, R> objectChooser, @NotNull final InsertionModeSet<G, A, R> insertionModeSet) {
122  super("selection");
123  this.objectChooser = objectChooser;
124  this.insertionModeSet = insertionModeSet;
126  }
127 
128  @Override
129  public void pressed(@NotNull final MouseOpEvent<G, A, R> e) {
130  final Point mapLoc = e.getMapLocation();
131  if (mapLoc == null) {
132  return;
133  }
134  final int mod = e.getModifiers();
135  final MapCursor<G, A, R> mapCursor = e.getMapCursor();
136  mapCursor.beginTransaction();
137  try {
138  // left mouse button: select squares
139  // Throw away old selection if neither SHIFT nor CTRL is not pressed
140  if ((mod & (InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK)) == 0) {
141  mapCursor.deactivate();
142  }
143  mapCursor.setLocation(mapLoc);
144  mapCursor.dragStart();
145  } finally {
146  mapCursor.endTransaction();
147  }
148  }
149 
150  @Override
151  public void clicked(@NotNull final MouseOpEvent<G, A, R> e) {
152  }
153 
154  @Override
155  public void dragged(@NotNull final MouseOpEvent<G, A, R> e) {
156  e.getMapCursor().dragTo(e.getMapLocation());
157  }
158 
159  @Override
160  public void moved(@NotNull final MouseOpEvent<G, A, R> e) {
161  }
162 
163  @Override
164  public void released(@NotNull final MouseOpEvent<G, A, R> e) {
165  final MapCursor<G, A, R> mapCursor = e.getMapCursor();
166  final int modifiers = e.getModifiers();
167  if (mapCursor.isOnGrid(e.getMapLocation())) {
168  if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0) {
169  if ((modifiers & InputEvent.CTRL_DOWN_MASK) == 0) {
170  mapCursor.dragSelect(SelectionMode.ADD, true);
171  } else {
172  mapCursor.dragSelect(SelectionMode.FLIP, true);
173  }
174  } else if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0) {
175  mapCursor.dragSelect(SelectionMode.SUB, true);
176  } else {
177  mapCursor.dragSelect(SelectionMode.ADD, false);
178  }
179  } else {
180  mapCursor.dragRelease();
181  }
182 
183  if (selectionToolAutoFill) {
184  final int modeIndex = modeComboBox.getSelectedIndex();
185  final InsertionMode<G, A, R> insertionMode;
186  switch (modeIndex) {
187  case MODE_AUTO:
188  insertionMode = insertionModeSet.getAutoInsertionMode();
189  break;
190 
191  case MODE_TOPMOST:
192  insertionMode = insertionModeSet.getTopmostInsertionMode();
193  break;
194 
195  case MODE_ABOVE_FLOOR:
196  insertionMode = insertionModeSet.getAboveFloorInsertionMode();
197  break;
198 
199  case MODE_BELOW_FLOOR:
200  insertionMode = insertionModeSet.getBelowFloorInsertionMode();
201  break;
202 
203  case MODE_BOTTOMMOST:
204  insertionMode = insertionModeSet.getBottommostInsertionMode();
205  break;
206 
207  default:
208  throw new AssertionError();
209  }
210  final MapView<G, A, R> mapView = e.getMapView();
211  FillUtils.fill(mapView.getMapControl().getMapModel(), mapView.getSelectedSquares(), insertionMode, objectChooser.getSelections(), -1, false);
212  }
213  }
214 
215  @Nullable
216  @Override
217  public Component createOptionsView() {
218  final Container panel = new JPanel();
219  panel.setLayout(new GridBagLayout());
220 
221  final GridBagConstraints gbcLabel = new GridBagConstraints();
222  gbcLabel.anchor = GridBagConstraints.EAST;
223 
224  final GridBagConstraints gbcComboBox = new GridBagConstraints();
225  gbcComboBox.fill = GridBagConstraints.HORIZONTAL;
226  gbcComboBox.weightx = 1.0;
227  gbcComboBox.gridwidth = GridBagConstraints.REMAINDER;
228 
229  final GridBagConstraints gbcCheckBox = new GridBagConstraints();
230  gbcCheckBox.fill = GridBagConstraints.HORIZONTAL;
231  gbcCheckBox.gridwidth = GridBagConstraints.REMAINDER;
232 
233  panel.add(autoFillAction.createCheckBox(), gbcCheckBox);
234  panel.add(SwingUtils.createLabel("selectionTool.mode", modeComboBox), gbcLabel);
235  panel.add(modeComboBox, gbcComboBox);
236  return panel;
237  }
238 
243  @NotNull
244  private static JComboBox<?> createModeComboBox() {
245  final String[] options = { ActionBuilderUtils.getString(ACTION_BUILDER, "selectionTool.mode.auto"), ActionBuilderUtils.getString(ACTION_BUILDER, "selectionTool.mode.topmost"), ActionBuilderUtils.getString(ACTION_BUILDER, "selectionTool.mode.aboveFloor"), ActionBuilderUtils.getString(ACTION_BUILDER, "selectionTool.mode.belowFloor"), ActionBuilderUtils.getString(ACTION_BUILDER, "selectionTool.mode.bottommost"), };
246  final JComboBox<?> comboBox = new JComboBox<>(options);
247  comboBox.setToolTipText(ActionBuilderUtils.getString(ACTION_BUILDER, "selectionTool.mode.shortdescription"));
248  return comboBox;
249  }
250 
255  @ActionMethod
256  public boolean isSelectionToolAutoFill() {
257  return selectionToolAutoFill;
258  }
259 
264  @ActionMethod
265  public void setSelectionToolAutoFill(final boolean selectionToolAutoFill) {
266  if (this.selectionToolAutoFill == selectionToolAutoFill) {
267  return;
268  }
269  this.selectionToolAutoFill = selectionToolAutoFill;
271  }
272 
278  modeComboBox.setEnabled(selectionToolAutoFill);
279  }
280 
281 }
Base class for the default provided tools.
void dragSelect(@NotNull final SelectionMode selectionMode, final boolean forceSelect)
Leave drag mode and select pre-selection using selectionMode.
Definition: MapCursor.java:337
InsertionMode< G, A, R > getAutoInsertionMode()
Returns the "auto" insertion mode.
List< MapSquare< G, A, R > > getSelectedSquares()
Returns the selected squares.
Graphical User Interface of Gridarta.
void selectionToolAutoFillChanged()
Updates the GUI state to reflect the current selectionToolAutoFill state.
final JComboBox<?> modeComboBox
The JComboBox for selecting the insertion mode.
static final ActionBuilder ACTION_BUILDER
Action Builder.
final ObjectChooser< G, A, R > objectChooser
The object chooser to update.
MapCursor provides methods to move and drag on map.
Definition: MapCursor.java:57
static final int MODE_ABOVE_FLOOR
Index into modeComboBox: insert above floor.
MapControl< G, A, R > getMapControl()
Return the controller of this view.
void pressed(@NotNull final MouseOpEvent< G, A, R > e)
final void beginTransaction()
Start a new transaction.
Definition: MapCursor.java:488
Utility class for Swing related functions.
Definition: SwingUtils.java:37
final void endTransaction()
End a transaction.
Definition: MapCursor.java:506
boolean isOnGrid(@Nullable final Point p)
Check if point is on grid.
Definition: MapCursor.java:379
MapModel< G, A, R > getMapModel()
Returns the map model.
static String getString(@NotNull final ActionBuilder actionBuilder, @NotNull final String key, @NotNull final String defaultValue)
Returns the value of a key.
void setLocation(@NotNull final Point p)
Move cursor to a new location.
Definition: MapCursor.java:235
Base package of all Gridarta classes.
InsertionMode< G, A, R > getAboveFloorInsertionMode()
Returns the "above floor" insertion mode.
Reflects a game object (object on a map).
Definition: GameObject.java:36
InsertionMode< G, A, R > getBottommostInsertionMode()
Returns the "bottommost" insertion mode.
InsertionMode< G, A, R > getTopmostInsertionMode()
Returns the "topmost" insertion mode.
GameObjects are the objects based on Archetypes found on maps.
SelectionTool(@NotNull final ObjectChooser< G, A, R > objectChooser, @NotNull final InsertionModeSet< G, A, R > insertionModeSet)
Create a BasicAbstractTool.
boolean selectionToolAutoFill
Whether auto-fill is enabled.
boolean isSelectionToolAutoFill()
Returns whether auto-fill is enabled.
final ToggleAction autoFillAction
The action for "ignore walls".
void setSelectionToolAutoFill(final boolean selectionToolAutoFill)
Sets whether auto-fill is enabled.
FLIP
All squares that are preselected change state of selection.
void dragRelease()
Leave drag mode and undo pre-selection.
Definition: MapCursor.java:318
List<? extends BaseObject< G, A, R, ?> > getSelections()
Returns the selected arches in the left-side panel.
Base classes for rendering maps.
static final int MODE_AUTO
Index into modeComboBox: guess insertion location.
final Point dragStart
Position where dragging has started.
Definition: MapCursor.java:70
void dragged(@NotNull final MouseOpEvent< G, A, R > e)
Utility class for ActionBuilder related functions.
static final int MODE_BOTTOMMOST
Index into modeComboBox: insert bottommost.
A MouseOpEvent is an event triggered for a MouseOpListener.
A map view consists of a map grid and a map cursor, and is attached to a map control.
Definition: MapView.java:43
void released(@NotNull final MouseOpEvent< G, A, R > e)
static Component createLabel(@NotNull final String key, @Nullable final Component component)
Create a javax.swing.JLabel instance.
Definition: SwingUtils.java:58
ADD
All squares that are preselected get selected.
Utility class implementing fill operations on map instances.
Definition: FillUtils.java:43
Modes that describe how squares get selected.
static JComboBox<?> createModeComboBox()
Create a JComboBox for selecting the scope to delete.
SUB
All squares that are preselected get unselected.
static final int MODE_BELOW_FLOOR
Index into modeComboBox: insert below floor.
Common base interface for ObjectChoosers.
final InsertionModeSet< G, A, R > insertionModeSet
The InsertionModeSet to use.
final void deactivate()
Cursor gets deactivated.
Definition: MapCursor.java:354
void clicked(@NotNull final MouseOpEvent< G, A, R > e)
InsertionMode< G, A, R > getBelowFloorInsertionMode()
Returns the "below floor" insertion mode.
static final int MODE_TOPMOST
Index into modeComboBox: insert topmost.
void moved(@NotNull final MouseOpEvent< G, A, R > e)