From: Frederick W. <fre...@us...> - 2012-01-22 12:38:30
|
LocalisedText.properties | 2 rails/ui/swing/GridPanel.java | 72 ++++--------- rails/ui/swing/ORUIManager.java | 2 rails/ui/swing/UpgradesPanel.java | 103 ++++++++++++++----- rails/ui/swing/hexmap/HexHighlightMouseListener.java | 29 +++++ rails/ui/swing/hexmap/HexMap.java | 11 ++ 6 files changed, 146 insertions(+), 73 deletions(-) New commits: commit 542796f830cf17bf0d8110b3eda239aa559e1ac3 Author: Frederick Weld <fre...@gm...> Date: Sun Jan 22 13:27:35 2012 +0100 Added hex highlighting for invalid tile lays (displays where tiles are) Motivation was that players often want to see what hex they have to update in order to make the needed tile available again. No configuration option has been added to disable such highlighting. diff --git a/rails/ui/swing/UpgradesPanel.java b/rails/ui/swing/UpgradesPanel.java index b650981..16486b5 100644 --- a/rails/ui/swing/UpgradesPanel.java +++ b/rails/ui/swing/UpgradesPanel.java @@ -19,6 +19,7 @@ import rails.game.action.*; import rails.game.correct.MapCorrectionAction; import rails.ui.swing.elements.ActionLabel; import rails.ui.swing.hexmap.GUIHex; +import rails.ui.swing.hexmap.HexHighlightMouseListener; import rails.ui.swing.hexmap.HexMap; public class UpgradesPanel extends Box implements MouseListener, ActionListener { @@ -201,6 +202,11 @@ public class UpgradesPanel extends Box implements MouseListener, ActionListener LocalText.getText(invalidTileUpgrades.get(tile))); hexLabel.setEnabled(false); hexLabel.setToolTipText(hexLabel.getToolTip()); + //highlight where tiles of this ID have been laid if no tiles left + if (invalidTileUpgrades.get(tile).equals(invalidUpgradeNoTilesLeft)) { + HexHighlightMouseListener.addMouseListener(hexLabel, + orUIManager, tile.getId(), true); + } upgradePanel.add(hexLabel); } } diff --git a/rails/ui/swing/hexmap/HexHighlightMouseListener.java b/rails/ui/swing/hexmap/HexHighlightMouseListener.java index 7cc2a96..89118b4 100644 --- a/rails/ui/swing/hexmap/HexHighlightMouseListener.java +++ b/rails/ui/swing/hexmap/HexHighlightMouseListener.java @@ -33,6 +33,7 @@ public class HexHighlightMouseListener implements MouseListener { HexMap hexMap; ORUIManager orUIManager; Portfolio portfolio; + int tileId; /** * lazy creation of the gui hex list for these reasons: @@ -104,6 +105,16 @@ public class HexHighlightMouseListener implements MouseListener { initPrivateCompanies(portfolio.getPrivateCompanies()); } + private void initTileIdHexList () { + //initially get hex map if not yet available + if (hexMap == null) hexMap = orUIManager.getMap(); + + //build the list of hexes the current tiles of which have the given tile ID + if (hexMap != null) { + guiHexList = hexMap.getHexesByCurrentTileId(tileId); + } + } + /** * @param orUIManager The OR UI manager containing the map where the highlighting * should occur @@ -128,6 +139,21 @@ public class HexHighlightMouseListener implements MouseListener { } /** + * @param tileId ID of the tile the occurrences of which should be highlighted on + * the map + * @param enableIrrespectiveOfHighlightConfig If true, the mouse listener is + * enabled irrespective of the base configuration. Needed since some highlighting + * should not be disabled by configuration. + */ + public static void addMouseListener(JComponent c,ORUIManager orUIManager,int tileId,boolean enableIrrespectiveOfHighlightConfig) { + if (isEnabled(enableIrrespectiveOfHighlightConfig)) { + HexHighlightMouseListener l = new HexHighlightMouseListener(orUIManager); + l.tileId = tileId; + c.addMouseListener(l); + } + } + + /** * @param p Private company the hexes associated to which are * to be highlighted (in case of events) * @param enableIrrespectiveOfHighlightConfig If true, the mouse listener is @@ -185,6 +211,7 @@ public class HexHighlightMouseListener implements MouseListener { public void mouseEntered(MouseEvent e) { if (portfolio != null) initPortfolioHexList(); + if (tileId != 0) initTileIdHexList(); initGuiHexList(); if (hexMap != null && guiHexList.size() > 0) { for (GUIHex guiHex : guiHexList) { @@ -199,7 +226,7 @@ public class HexHighlightMouseListener implements MouseListener { guiHex.removeHighlightRequest(); } } - if (portfolio != null) clearHexList(); + if (portfolio != null || tileId != 0) clearHexList(); } public void mouseClicked(MouseEvent e) { diff --git a/rails/ui/swing/hexmap/HexMap.java b/rails/ui/swing/hexmap/HexMap.java index 5d2188d..a9246a0 100644 --- a/rails/ui/swing/hexmap/HexMap.java +++ b/rails/ui/swing/hexmap/HexMap.java @@ -737,6 +737,17 @@ public abstract class HexMap implements MouseListener, { return selectedHex != null; } + + public List<GUIHex> getHexesByCurrentTileId (int tileId) { + List<GUIHex> hs = new ArrayList<GUIHex>(); + for (GUIHex h : hexes) { + TileI tile = h.getCurrentTile(); + if (tile != null && tile.getId() == tileId) { + hs.add(h); + } + } + return hs; + } public void setAllowedTileLays(List<LayTile> allowedTileLays) { commit 0085f9f6174978b9d8d4f41a4bec37da48d1a5a9 Author: Frederick Weld <fre...@gm...> Date: Sun Jan 22 12:42:57 2012 +0100 Added invalid tile lays to upgrade panel (grayed out & reason) Only two reasons are implementated (others do not appear to be valid): - no valid orientation - no tiles left Reasons are communicated by tooltips. diff --git a/LocalisedText.properties b/LocalisedText.properties index ee42f0c..ee9b8a4 100644 --- a/LocalisedText.properties +++ b/LocalisedText.properties @@ -435,6 +435,7 @@ NoSpecialProperty=No special property notExtra=not extra NoTile=No Tile NoTiles=At the moment there is no valid tile or upgrade for this hex. Select another hex or press the No Tile button. +NoTilesLeft=No tiles left NoTilesTag=No Tiles tag found in Tiles file NoTilesXML=No Tiles XML file specified NoToken=No Token @@ -451,6 +452,7 @@ NotBiddable=Item is not available for bidding NotYetFloated={0} has not yet floated. NotYetOperated={0} has not yet operated. NotYetStarted={0} is not yet started. +NoValidOrientation=No valid orientation NumberOfNormalTileLaysExceeded=Number of normal tile lays of colour {0} would be exceeded Obsolete4Trains=Delayed obsolescence 4-trains OCAmountEntry=free entry diff --git a/rails/ui/swing/ORUIManager.java b/rails/ui/swing/ORUIManager.java index 4bed76d..db96ac7 100644 --- a/rails/ui/swing/ORUIManager.java +++ b/rails/ui/swing/ORUIManager.java @@ -740,7 +740,7 @@ public class ORUIManager implements DialogOwner { } } - private boolean isTileUpgradeValid(GUIHex hex, TileI tile) { + public boolean isTileUpgradeValid(GUIHex hex, TileI tile) { // Check if the new tile must be connected to some other track return hex.isTileUpgradeValid(tile.getId(), getMustConnectRequirement(hex,tile)); diff --git a/rails/ui/swing/UpgradesPanel.java b/rails/ui/swing/UpgradesPanel.java index 7c67112..b650981 100644 --- a/rails/ui/swing/UpgradesPanel.java +++ b/rails/ui/swing/UpgradesPanel.java @@ -46,6 +46,11 @@ public class UpgradesPanel extends Box implements MouseListener, ActionListener new JButton(LocalText.getText(INIT_CANCEL_TEXT)); private JButton doneButton = new JButton(LocalText.getText(INIT_DONE_TEXT)); private HexMap hexMap; + + //list of tiles with an attached reason why it would represent an invalid upgrade + private Map<TileI,String> invalidTileUpgrades = null; + private static final String invalidUpgradeNoTilesLeft = "NoTilesLeft"; + private static final String invalidUpgradeNoValidOrientation = "NoValidOrientation"; protected static Logger log = Logger.getLogger(UpgradesPanel.class.getPackage().getName()); @@ -109,6 +114,22 @@ public class UpgradesPanel extends Box implements MouseListener, ActionListener } } } + + //determine invalid upgrades + //duplicates game engine logic to some degree + //but this is indispensable since the game engine's services not sufficient here + invalidTileUpgrades = new HashMap<TileI,String>(); + for (TileI tile : uiHex.getCurrentTile().getUpgrades(hex, currentPhase)) { + if (!orUIManager.tileUpgrades.contains(tile)) { + if (!currentPhase.isTileColourAllowed(tile.getColourName())) { + //current design decision: don't display tiles for invalid phases + } else if (!orUIManager.isTileUpgradeValid(uiHex, tile)) { + invalidTileUpgrades.put(tile, invalidUpgradeNoValidOrientation); + } else if (tile.countFreeTiles() == 0) { + invalidTileUpgrades.put(tile, invalidUpgradeNoTilesLeft); + } + } + } } public void showUpgrades() { @@ -164,37 +185,53 @@ public class UpgradesPanel extends Box implements MouseListener, ActionListener } else if (orUIManager.tileUpgrades == null) { ; - } else if (orUIManager.tileUpgrades.size() == 0) { - orUIManager.setMessage(LocalText.getText("NoTiles")); - } else { - for (TileI tile : orUIManager.tileUpgrades) { - BufferedImage hexImage = getHexImage(tile.getPictureId()); - ImageIcon hexIcon = new ImageIcon(hexImage); - - // Cheap n' Easy rescaling. - hexIcon.setImage(hexIcon.getImage().getScaledInstance( - (int) (hexIcon.getIconWidth() * GUIHex.NORMAL_SCALE * 0.8), - (int) (hexIcon.getIconHeight() * GUIHex.NORMAL_SCALE * 0.8), - Image.SCALE_SMOOTH)); - - HexLabel hexLabel = new HexLabel(hexIcon, tile.getId()); - hexLabel.setName(tile.getName()); - hexLabel.setTextFromTile(tile); - hexLabel.setOpaque(true); - hexLabel.setVisible(true); - hexLabel.setBorder(border); - hexLabel.addMouseListener(this); - - upgradePanel.add(hexLabel); + } else { + if (orUIManager.tileUpgrades.size() == 0) { + orUIManager.setMessage(LocalText.getText("NoTiles")); + } else { + for (TileI tile : orUIManager.tileUpgrades) { + HexLabel hexLabel = createHexLabel(tile,null); + hexLabel.addMouseListener(this); + upgradePanel.add(hexLabel); + } + } + if (invalidTileUpgrades != null) { + for (TileI tile : invalidTileUpgrades.keySet()) { + HexLabel hexLabel = createHexLabel(tile, + LocalText.getText(invalidTileUpgrades.get(tile))); + hexLabel.setEnabled(false); + hexLabel.setToolTipText(hexLabel.getToolTip()); + upgradePanel.add(hexLabel); + } } } - + upgradePanel.add(doneButton); upgradePanel.add(cancelButton); //repaint(); revalidate(); } + + private HexLabel createHexLabel(TileI tile,String toolTipHeaderLine) { + BufferedImage hexImage = getHexImage(tile.getPictureId()); + ImageIcon hexIcon = new ImageIcon(hexImage); + + // Cheap n' Easy rescaling. + hexIcon.setImage(hexIcon.getImage().getScaledInstance( + (int) (hexIcon.getIconWidth() * GUIHex.NORMAL_SCALE * 0.8), + (int) (hexIcon.getIconHeight() * GUIHex.NORMAL_SCALE * 0.8), + Image.SCALE_SMOOTH)); + + HexLabel hexLabel = new HexLabel(hexIcon, tile.getId(),toolTipHeaderLine); + hexLabel.setName(tile.getName()); + hexLabel.setTextFromTile(tile); + hexLabel.setOpaque(true); + hexLabel.setVisible(true); + hexLabel.setBorder(border); + + return hexLabel; + } // populate version for corrections public void showCorrectionTileUpgrades() { @@ -482,11 +519,15 @@ public class UpgradesPanel extends Box implements MouseListener, ActionListener int internalId; HexLabel(ImageIcon hexIcon, int internalId) { + this(hexIcon,internalId,null); + } + + HexLabel(ImageIcon hexIcon, int internalId, String toolTipHeaderLine) { super(hexIcon); this.internalId = internalId; - this.setToolTip(); + this.setToolTip(toolTipHeaderLine); } - + int getInternalId() { return internalId; } @@ -508,8 +549,14 @@ public class UpgradesPanel extends Box implements MouseListener, ActionListener } protected void setToolTip() { + setToolTip(null); + } + protected void setToolTip (String headerLine) { TileI currentTile = orUIManager.getGameUIManager().getGameManager().getTileManager().getTile(internalId); StringBuffer tt = new StringBuffer("<html>"); + if (headerLine != null && !headerLine.equals("")) { + tt.append("<b><u>"+headerLine+"</u></b><br>"); + } tt.append("<b>Tile</b>: ").append(currentTile.getName()); // or // getId() if (currentTile.hasStations()) { commit 4a2e4fb1758d403f25abfb63a311ddd6d34323c9 Author: Frederick Weld <fre...@gm...> Date: Sun Jan 22 07:01:45 2012 +0100 Refactored GridPanel's DynamicBorders Generalized symmetric / asymmetric dynamic borders to a general one. diff --git a/rails/ui/swing/GridPanel.java b/rails/ui/swing/GridPanel.java index a64f955..6644dd1 100644 --- a/rails/ui/swing/GridPanel.java +++ b/rails/ui/swing/GridPanel.java @@ -126,8 +126,8 @@ implements ActionListener, KeyListener { //- outer border: grid table lines (in wide_gap - narrow_gap thickness) comp.setBorder(new FieldBorder(comp.getBorder(), - new DynamicSymmetricBorder(cellOutlineColor,NARROW_GAP), - new DynamicAsymmetricBorder(tableBorderColor,padTop,padLeft,padBottom,padRight))); + new DynamicBorder(cellOutlineColor,NARROW_GAP), + new DynamicBorder(tableBorderColor,padTop,padLeft,padBottom,padRight))); gridPanel.add(comp, gbc); @@ -249,15 +249,15 @@ implements ActionListener, KeyListener { private class FieldBorder extends CompoundBorder { private static final long serialVersionUID = 1L; Border nativeInnerBorder; - DynamicAsymmetricBorder highlightedInnerBorder; - DynamicSymmetricBorder outlineBorder; - DynamicAsymmetricBorder outerBorder; - public FieldBorder(Border innerBorder,DynamicSymmetricBorder outlineBorder,DynamicAsymmetricBorder outerBorder) { + DynamicBorder highlightedInnerBorder; + DynamicBorder outlineBorder; + DynamicBorder outerBorder; + public FieldBorder(Border innerBorder,DynamicBorder outlineBorder,DynamicBorder outerBorder) { super(new CompoundBorder(outerBorder,outlineBorder),innerBorder); this.nativeInnerBorder = innerBorder; this.outlineBorder = outlineBorder; this.outerBorder = outerBorder; - this.highlightedInnerBorder = new DynamicAsymmetricBorder( + this.highlightedInnerBorder = new DynamicBorder( highlightedBorderColor, nativeInnerBorder.getBorderInsets(null).top, nativeInnerBorder.getBorderInsets(null).left, @@ -272,65 +272,45 @@ implements ActionListener, KeyListener { } /** - * A line border providing methods for changing the look + * A potentially asymmetric line border providing methods for changing the look * @author Frederick Weld * */ - private class DynamicSymmetricBorder extends AbstractBorder { + private class DynamicBorder extends AbstractBorder { private static final long serialVersionUID = 1L; - private int thickness; + private int padTop, padLeft, padBottom, padRight; private Color borderColor; private boolean isHighlighted = false; - public DynamicSymmetricBorder (Color borderColor,int thickness) { - this.thickness = thickness; + + public DynamicBorder (Color borderColor,int symmetricPad) { + this.padTop = symmetricPad; + this.padLeft = symmetricPad; + this.padBottom = symmetricPad; + this.padRight = symmetricPad; + this.borderColor = borderColor; + } + + public DynamicBorder (Color borderColor,int padTop, int padLeft, int padBottom, int padRight) { + this.padTop = padTop; + this.padLeft = padLeft; + this.padBottom = padBottom; + this.padRight = padRight; this.borderColor = borderColor; } + public void setHighlight(boolean isToBeHighlighted) { if (isHighlighted != isToBeHighlighted) { isHighlighted = isToBeHighlighted; } } - + public void paintBorder(Component c,Graphics g, int x, int y, int width,int height) { Graphics2D g2d = (Graphics2D)g; - Stroke oldStroke = g2d.getStroke(); - g2d.setStroke(new BasicStroke(thickness)); if (isHighlighted) { g2d.setColor(highlightedBorderColor); } else { g2d.setColor(borderColor); } - g2d.drawRect(x, y, width-1, height-1); - g2d.setStroke(oldStroke); - } - - public Insets getBorderInsets (Component c) { - return new Insets(thickness,thickness,thickness,thickness); - } - - public boolean isBorderOpaque() { - return true; - } - } - /** - * An asymmetric line border providing methods for changing the look - * @author Frederick Weld - * - */ - private class DynamicAsymmetricBorder extends AbstractBorder { - private static final long serialVersionUID = 1L; - private int padTop, padLeft, padBottom, padRight; - private Color borderColor; - public DynamicAsymmetricBorder (Color borderColor,int padTop, int padLeft, int padBottom, int padRight) { - this.padTop = padTop; - this.padLeft = padLeft; - this.padBottom = padBottom; - this.padRight = padRight; - this.borderColor = borderColor; - } - public void paintBorder(Component c,Graphics g, int x, int y, int width,int height) { - Graphics2D g2d = (Graphics2D)g; - g2d.setColor(borderColor); Stroke oldStroke = g2d.getStroke(); if (padTop > 0) { g2d.setStroke(new BasicStroke(padTop)); |