Lift active unit/tile logic out of MapViewer.

This commit is contained in:
Mike Pope 2018-03-22 09:33:31 +10:30
parent c807986d34
commit cd14bd38f6
4 changed files with 99 additions and 112 deletions

View File

@ -74,25 +74,29 @@ public final class CanvasMouseListener extends FreeColClientHolder
if (tile == null) return;
// Only process events that could not have been gotos.
final Unit unit = getGUI().getActiveUnit();
final GUI gui = getGUI();
final Unit active = gui.getActiveUnit();
if (e.getClickCount() > 1
|| unit == null
|| unit.getTile() == tile
|| active == null
|| active.getTile() == tile
|| !canvas.isDrag(e.getX(), e.getY())) {
if (tile.hasSettlement()) {
getGUI().showTileSettlement(tile);
} else if (unit == null || unit.getTile() != tile) {
if (!tile.isExplored()) {
gui.setSelectedTile(tile);
gui.setViewMode(GUI.VIEW_TERRAIN_MODE);
} if (tile.hasSettlement()) {
gui.showTileSettlement(tile);
} else if (active == null || active.getTile() != tile) {
Unit other = tile.getFirstUnit();
if (other != null && getMyPlayer().owns(other)) {
getGUI().setActiveUnit(other);
getGUI().setViewMode(GUI.MOVE_UNITS_MODE);
gui.setActiveUnit(other);
gui.setViewMode(GUI.MOVE_UNITS_MODE);
} else {
getGUI().setSelectedTile(tile);
getGUI().setViewMode(GUI.VIEW_TERRAIN_MODE);
gui.setSelectedTile(tile);
gui.setViewMode(GUI.VIEW_TERRAIN_MODE);
}
} else {
getGUI().setSelectedTile(tile);
getGUI().setViewMode(GUI.VIEW_TERRAIN_MODE);
gui.setSelectedTile(tile);
gui.setViewMode(GUI.VIEW_TERRAIN_MODE);
}
}
}

View File

@ -1672,11 +1672,8 @@ public class GUI extends FreeColClientHolder {
* Set the active unit.
*
* @param unit The {@code Unit} to activate.
* @return True if the focus was set.
*/
public boolean setActiveUnit(Unit unit) {
return false;
}
public void setActiveUnit(Unit unit) {}
/**
* Center the active unit.
@ -1696,11 +1693,8 @@ public class GUI extends FreeColClientHolder {
* Set the selected tile.
*
* @param tile The new selected {@code Tile}.
* @return True if setting the tile changes the focus.
*/
public boolean setSelectedTile(Tile tile) {
return true;
}
public void setSelectedTile(Tile tile) {}
// Zoom controls

View File

@ -256,6 +256,42 @@ public final class MapViewer extends FreeColClientHolder {
}
}
/**
* Gets the active unit.
*
* @return The {@code Unit}.
*/
public Unit getActiveUnit() {
return this.activeUnit;
}
/**
* Sets the active unit.
*
* @param activeUnit The new active {@code Unit}.
*/
public void setActiveUnit(Unit activeUnit) {
this.activeUnit = activeUnit;
}
/**
* Gets the selected tile.
*
* @return The {@code Tile} selected.
*/
public Tile getSelectedTile() {
return this.selectedTile;
}
/**
* Sets the selected tile.
*
* @param tile The new selected {@code Tile}.
*/
public void setSelectedTile(Tile tile) {
this.selectedTile = tile;
}
/**
* Centers the map on the selected unit.
*/
@ -918,56 +954,6 @@ public final class MapViewer extends FreeColClientHolder {
&& tile.getX() >= leftColumn && tile.getX() <= rightColumn;
}
/**
* Gets the selected tile.
*
* @return The {@code Tile} selected.
*/
Tile getSelectedTile() {
return selectedTile;
}
/**
* Selects the tile at the specified position. There are two
* possible cases:
*
* <ol>
* <li>If the tile contains a unit that can become active, then
* that unit will be set as the active unit.
* <li>If not, the {@code selectedTile} will become the map focus.
* </ol>
*
* If a unit is active and is located on the selected tile,
* then nothing (except perhaps a map reposition) will happen.
*
* @param newTile The {@code Tile}, the tile to be selected
* @return True if the focus was set.
* @see #getSelectedTile
* @see #setActiveUnit
* @see #setFocus(Tile)
*/
boolean setSelectedTile(Tile newTile) {
Tile oldTile = this.selectedTile;
boolean ret = false;
selectedTile = newTile;
// Check for refocus
if (!onScreen(newTile)
|| getClientOptions().getBoolean(ClientOptions.ALWAYS_CENTER)) {
gui.setFocus(newTile);
ret = true;
} else {
if (oldTile != null) {
gui.refreshTile(oldTile);
}
if (newTile != null) {
gui.refreshTile(newTile);
}
}
return ret;
}
/**
* Gets the unit that should be displayed on the given tile.
*
@ -1009,42 +995,6 @@ public final class MapViewer extends FreeColClientHolder {
return result;
}
/**
* Gets the active unit.
*
* @return The {@code Unit}.
* @see #setActiveUnit
*/
Unit getActiveUnit() {
return activeUnit;
}
/**
* Sets the active unit.
*
* @param activeUnit The new active {@code Unit}.
* @return True if the focus was set.
*/
boolean setActiveUnit(Unit activeUnit) {
// Don't select a unit with zero moves left. -sjm
// The user might what to check the status of a unit - SG
Tile tile = (activeUnit == null) ? null : activeUnit.getTile();
this.activeUnit = activeUnit;
if (activeUnit == null || tile == null) {
gui.getCanvas().stopGoto();
} else {
changeViewMode(GUI.MOVE_UNITS_MODE);
updateCurrentPathForActiveUnit();
if (!gui.setSelectedTile(tile)
|| getClientOptions().getBoolean(ClientOptions.JUMP_TO_ACTIVE_UNIT)) {
gui.setFocus(tile);
return true;
}
}
return false;
}
/**
* Checks if there is currently a goto operation on the mapboard.
*

View File

@ -174,6 +174,26 @@ public class SwingGUI extends GUI {
return null;
}
/**
* Internal version of setSelectedTile allowing focus override.
*
* @param newTile The new {@code Tile} to select.
* @param refocus If true, always refocus.
*/
private void setSelectedTile(Tile newTile, boolean refocus) {
final Tile oldTile = getSelectedTile();
refocus = newTile != null && (refocus || !mapViewer.onScreen(newTile)
|| getClientOptions().getBoolean(ClientOptions.ALWAYS_CENTER));
if (refocus) {
setFocus(newTile);
} else {
if (oldTile != null) refreshTile(oldTile);
if (newTile != null) refreshTile(newTile);
}
mapViewer.setSelectedTile(newTile);
}
// TODO
private void setFocusImmediately(Tile tileToFocus) {
mapViewer.setFocus(tileToFocus);
Dimension size = canvas.getSize();
@ -957,14 +977,34 @@ public class SwingGUI extends GUI {
* {@inheritDoc}
*/
@Override
public boolean setActiveUnit(Unit unit) {
boolean result = mapViewer.setActiveUnit(unit);
public void setActiveUnit(Unit unit) {
final Unit old = getActiveUnit();
Tile tile = null;
if (unit == null || (tile = unit.getTile()) == null) {
canvas.stopGoto();
}
mapViewer.setActiveUnit(unit);
// Automatic mode switch when switching to/from null active unit
if (unit != null && old == null) {
setViewMode(GUI.MOVE_UNITS_MODE);
// Bring the selected tile along with the unit
if (tile != getSelectedTile()) {
setSelectedTile(tile, tile != null
&& getClientOptions().getBoolean(ClientOptions.JUMP_TO_ACTIVE_UNIT));
}
} else if (unit == null && old != null) {
tile = getSelectedTile();
if (tile != null) setViewMode(GUI.VIEW_TERRAIN_MODE);
}
updateMapControls();
updateMenuBar();
// TODO: why do we have to refresh the entire canvas?
if (unit != null && !getMyPlayer().owns(unit)) {
canvas.refresh();
}
return result;
}
/**
@ -990,11 +1030,10 @@ public class SwingGUI extends GUI {
* {@inheritDoc}
*/
@Override
public boolean setSelectedTile(Tile newTileToSelect) {
boolean result = mapViewer.setSelectedTile(newTileToSelect);
public void setSelectedTile(Tile newTile) {
setSelectedTile(newTile, false);
updateMapControls();
updateMenuBar();
return result;
}