From: Stefan F. <ste...@us...> - 2012-01-04 14:18:32
|
LocalisedText.properties | 5 + data/Properties.xml | 5 + rails/ui/swing/ORPanel.java | 111 ++++++++++++++++++++++++++------------ rails/ui/swing/hexmap/GUIHex.java | 7 ++ rails/ui/swing/hexmap/HexMap.java | 40 +++++++++---- 5 files changed, 119 insertions(+), 49 deletions(-) New commits: commit b219711f9415088441fe6cbc9d356cdce079e9d9 Author: Frederick Weld <fre...@gm...> Date: Tue Jan 3 21:15:32 2012 +0100 Added option to display optimal routes of currently active company If this option is chosen, optimal routes are displayed for each OR step. This option replaces prior keyboard shortcut Ctrl+N which had some disadvantages (popup, optimal route display only temporary). The config section "map/report" has been split as it contained too many items after adding aforementioned option. Signed-off-by: Stefan Frey <ste...@we...> diff --git a/LocalisedText.properties b/LocalisedText.properties index a3fdd12..8a1f4f7 100644 --- a/LocalisedText.properties +++ b/LocalisedText.properties @@ -170,6 +170,7 @@ ComponentManagerNotReconfigured=Cannot reconfigure the ComponentManager. ComponentManagerNotYetConfigured=ComponentManager has not yet been configured. Config.infoText.locale=<html>te_ST shows local text keys. <br> Requires restart.</html> Config.infoText.default_players=Enter player names separated by commas. +Config.infoText.map.displayCurrentRoutes=If enabled, optimal train routes are displayed for the company which is currently taking its turn. Config.infoText.sound.backgroundMusic.stockRound=<html>Enter assignment of music files (mp3) to phases.<ul><li>Separate the assignments by commas.<li>Each assignment has the syntax phaseName=complete file path<li>Default music is defined by omitting "phaseName=" in the assignment.</ul><strong>Examples:</strong><ul><li>Set default music: <br><code>c:\SR-default.mp3</code><li>Set phase-dependent music and a default (for trains above 6): <br><code>2=c:\SR-2.mp3,3=c:\SR-3.mp3,4=c:\SR-4.mp3,5=c:\SR-5.mp3,6=c:\SR-6.mp3,c:\SR-D.mp3</code></ul> </html> Config.infoText.sound.backgroundMusic.operatingRound=<html>Enter assignment of music files (mp3) to phases.<ul><li>Separate the assignments by commas.<li>Each assignment has the syntax phaseName=complete file path<li>Default music is defined by omitting "phaseName=" in the assignment.</ul><strong>Examples:</strong><ul><li>Set default music: <br><code>c:\OR-default.mp3</code><li>Set phase-dependent music and a default (for trains above 6): <br><code>2=c:\OR-2.mp3,3=c:\OR-3.mp3,4=c:\OR-4.mp3,5=c:\OR-5.mp3,6=c:\OR-6.mp3,c:\OR-D.mp3</code></ul> </html> Config.label.default_game=Default game @@ -180,6 +181,7 @@ Config.label.font.ui.style=Font style Config.label.local.player.name=Local player (for pbem) Config.label.locale=Language setting Config.label.map.autoscroll=Map autoscroll +Config.label.map.displayCurrentRoutes=Display routes of active company Config.label.map.image.display=Display background map Config.label.map.zoomstep=Map zoomstep Config.label.money_format=Money format @@ -209,9 +211,10 @@ Config.section.Format=Format/Colors Config.section.General=General Config.section.Log=Log Config.section.Font=Fonts +Config.section.Map=Map Config.section.Save=Save Config.section.Sound=Sound -Config.section.UI=Map/Report +Config.section.Windows=Windows ConfirmToken=Press Lay Token to confirm token, click another city hex, or press the No Token button. connected=connected CorrectCashAddMoney=CORRECTION: {0} receives {1} from the bank diff --git a/data/Properties.xml b/data/Properties.xml index 231e6e6..29e377f 100644 --- a/data/Properties.xml +++ b/data/Properties.xml @@ -27,10 +27,13 @@ <Property name="font.ui.style" type="LIST" values="plain,bold" initClass="rails.ui.swing.GameUIManager" initMethod="updateUILookAndFeel" initParameter="no" /> </Section> - <Section name="UI"> + <Section name="Map"> <Property name="map.autoscroll" type="BOOLEAN" /> <Property name="map.zoomstep" type="INTEGER" /> <Property name="map.image.display" type="BOOLEAN" /> + <Property name="map.displayCurrentRoutes" type="BOOLEAN" /> + </Section> + <Section name="Windows"> <Property name="report.window.type" type="LIST" values="static,dynamic" /> <Property name="report.window.open" type="BOOLEAN" /> <Property name="report.window.editable" type="BOOLEAN" /> diff --git a/rails/ui/swing/ORPanel.java b/rails/ui/swing/ORPanel.java index e88b788..6c1be18 100644 --- a/rails/ui/swing/ORPanel.java +++ b/rails/ui/swing/ORPanel.java @@ -15,6 +15,7 @@ import org.jgrapht.graph.SimpleGraph; import rails.algorithms.*; import rails.common.GuiDef; import rails.common.LocalText; +import rails.common.parser.Config; import rails.game.*; import rails.game.action.*; import rails.ui.swing.elements.*; @@ -115,6 +116,10 @@ implements ActionListener, KeyListener, RevenueListener { private PublicCompanyI orComp = null; + //for displaying routes of the currently active company + private RevenueAdapter currentRoutesRevenueAdapter = null; + + //for displaying routes of the "set revenue" step private RevenueAdapter revenueAdapter = null; private Thread revenueThread = null; @@ -713,6 +718,7 @@ implements ActionListener, KeyListener, RevenueListener { orUIManager.getMap().setTrainPaths(null); //but retain paths already existing before if (revenueAdapter != null) revenueAdapter.drawOptimalRunAsPath(orUIManager.getMap()); + if (currentRoutesRevenueAdapter != null) currentRoutesRevenueAdapter.drawOptimalRunAsPath(orUIManager.getMap()); orUIManager.getMap().repaint(); } } @@ -732,8 +738,21 @@ implements ActionListener, KeyListener, RevenueListener { undoButton.setEnabled(false); redoButton.setEnabled(false); + removeCurrentRoutes(); } + private void redrawRoutes() { + if (revenueAdapter != null && displayRevenueRoutes()) { + revenueAdapter.drawOptimalRunAsPath(orUIManager.getMap()); + orUIManager.getMap().repaint(); + } + if (currentRoutesRevenueAdapter != null && displayCurrentRoutes()) { + currentRoutesRevenueAdapter.drawOptimalRunAsPath(orUIManager.getMap()); + orUIManager.getMap().repaint(); + } + + } + public void actionPerformed(ActionEvent actor) { // What kind action has been taken? @@ -762,34 +781,19 @@ implements ActionListener, KeyListener, RevenueListener { orUIManager.processAction(command, executedActions); } else if (source == zoomIn) { orWindow.getMapPanel().zoom(true); - if (revenueAdapter != null) { - revenueAdapter.drawOptimalRunAsPath(orUIManager.getMap()); - orUIManager.getMap().repaint(); - } + redrawRoutes(); } else if (source == zoomOut) { orWindow.getMapPanel().zoom(false); - if (revenueAdapter != null) { - revenueAdapter.drawOptimalRunAsPath(orUIManager.getMap()); - orUIManager.getMap().repaint(); - } + redrawRoutes(); } else if (source == fitToWindow) { orWindow.getMapPanel().fitToWindow(); - if (revenueAdapter != null) { - revenueAdapter.drawOptimalRunAsPath(orUIManager.getMap()); - orUIManager.getMap().repaint(); - } + redrawRoutes(); } else if (source == fitToWidth) { orWindow.getMapPanel().fitToWidth(); - if (revenueAdapter != null) { - revenueAdapter.drawOptimalRunAsPath(orUIManager.getMap()); - orUIManager.getMap().repaint(); - } + redrawRoutes(); } else if (source == fitToHeight) { orWindow.getMapPanel().fitToHeight(); - if (revenueAdapter != null) { - revenueAdapter.drawOptimalRunAsPath(orUIManager.getMap()); - orUIManager.getMap().repaint(); - } + redrawRoutes(); } else if (source == calibrateMap) { MapManager mapManager = orUIManager.getMap().getMapManager(); String offsetX = JOptionPane.showInputDialog(this, "Change translation in X-dimension", mapManager.getMapXOffset()); @@ -859,19 +863,54 @@ implements ActionListener, KeyListener, RevenueListener { } /** - * Sets the keyboard shortcut (CTRL+N) for displaying routes of the given company + * + * @return True if route calculation is active and if the routes of the currently + * active company are not displayed all the time (only if this is not the case, + * it makes sense to display routes for the set revenue step) */ - private void setKeyboardShortcutForNetwork(PublicCompanyI orComp) { - if (networkInfoMenu == null) return; - for (int i=0 ; i<networkInfoMenu.getItemCount(); i++) { - JMenuItem item = networkInfoMenu.getItem(i); - if (item.getAccelerator() != null) item.setAccelerator(null); - if (item.getText().equals(orComp.getName())) { - item.setAccelerator(KeyStroke.getKeyStroke( - KeyEvent.VK_N , ActionEvent.CTRL_MASK )); - } + private boolean displayRevenueRoutes() { + return (orUIManager.gameUIManager.getGameParameterAsBoolean(GuiDef.Parm.ROUTE_HIGHLIGHT) + && "no".equalsIgnoreCase(Config.get("map.displayCurrentRoutes"))); + } + + /** + * + * @return True if the routes of the currently active company should be displayed. + * As a prerequisite of this feature, route highlighting has to be enabled/supported. + */ + private boolean displayCurrentRoutes() { + return (orUIManager.gameUIManager.getGameParameterAsBoolean(GuiDef.Parm.ROUTE_HIGHLIGHT) + && "yes".equalsIgnoreCase(Config.get("map.displayCurrentRoutes"))); + } + + /** + * routes of the current company are removed from the map + */ + private void removeCurrentRoutes() { + if (currentRoutesRevenueAdapter != null) { + orUIManager.getMap().setTrainPaths(null); + currentRoutesRevenueAdapter = null; + orUIManager.getMap().repaint(); } - + } + + private void updateCurrentRoutes() { + + //remove current routes also if display option is not active + //(as it could have just been turned off) + removeCurrentRoutes(); + + //calculate routes for the current company + if (displayCurrentRoutes()) { + GameManagerI gm = orUIManager.getGameUIManager().getGameManager(); + currentRoutesRevenueAdapter = RevenueAdapter.createRevenueAdapter( + gm, orComp, gm.getCurrentPhase()); + currentRoutesRevenueAdapter.initRevenueCalculator(true); + currentRoutesRevenueAdapter.calculateRevenue(); + currentRoutesRevenueAdapter.drawOptimalRunAsPath(orUIManager.getMap()); + orUIManager.getMap().repaint(); + } + } public void initORCompanyTurn(PublicCompanyI orComp, int orCompIndex) { @@ -890,7 +929,7 @@ implements ActionListener, KeyListener, RevenueListener { button2.setEnabled(false); button3.setEnabled(false); - setKeyboardShortcutForNetwork(orComp); + updateCurrentRoutes(); } public void initTileLayingStep() { @@ -940,8 +979,10 @@ implements ActionListener, KeyListener, RevenueListener { public void revenueUpdate(int bestRevenue, boolean finalResult) { revenueSelect[orCompIndex].setValue(bestRevenue); if (finalResult) { - revenueAdapter.drawOptimalRunAsPath(orUIManager.getMap()); - orUIManager.getMap().repaint(); + if (displayRevenueRoutes()) { + revenueAdapter.drawOptimalRunAsPath(orUIManager.getMap()); + orUIManager.getMap().repaint(); + } orUIManager.addInformation("Best Run Value = " + bestRevenue + " with " + Util.convertToHtml(revenueAdapter.getOptimalRunPrettyPrint(false))); orUIManager.addDetail(Util.convertToHtml(revenueAdapter.getOptimalRunPrettyPrint(true))); @@ -949,7 +990,7 @@ implements ActionListener, KeyListener, RevenueListener { } public void stopRevenueUpdate() { - orUIManager.getMap().setTrainPaths(null); + if (displayRevenueRoutes()) orUIManager.getMap().setTrainPaths(null); if (revenueThread != null) { revenueThread.interrupt(); revenueThread = null; commit 3edaa4dd563f7638f5cd13c758d4ffa757a2f3c6 Author: Frederick Weld <fre...@gm...> Date: Tue Jan 3 20:05:42 2012 +0100 Fixed hexmap layering (tokens and text now displayed on top of routes) Before, route strokes were placed on top of the map, thus hiding potentially valuable information. This has been adjusted: Train routes are now drawn on top of the hexes but below any further map information (tokens, home bases, texts for costs, special tokens) Signed-off-by: Stefan Frey <ste...@we...> diff --git a/rails/ui/swing/hexmap/GUIHex.java b/rails/ui/swing/hexmap/GUIHex.java index e083c44..0ed9017 100644 --- a/rails/ui/swing/hexmap/GUIHex.java +++ b/rails/ui/swing/hexmap/GUIHex.java @@ -332,7 +332,7 @@ public class GUIHex implements ViewObject { return polygon; } - public void paint(Graphics g) { + public void paintHexagon(Graphics g) { Graphics2D g2 = (Graphics2D) g; tilePainted = provisionalGUITile != null && hexMap.isTilePainted(provisionalGUITile.getTileId()) @@ -389,6 +389,11 @@ public class GUIHex implements ViewObject { } if (tilePainted) paintOverlay(g2); + } + + public void paintTokensAndText(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + paintStationTokens(g2); paintOffStationTokens(g2); diff --git a/rails/ui/swing/hexmap/HexMap.java b/rails/ui/swing/hexmap/HexMap.java index 7ae00c8..09d2492 100644 --- a/rails/ui/swing/hexmap/HexMap.java +++ b/rails/ui/swing/hexmap/HexMap.java @@ -301,7 +301,7 @@ public abstract class HexMap extends JComponent implements MouseListener, if (g.hitClip(hexrect.x, hexrect.y, hexrect.width, hexrect.height)) { - hex.paint(g); + hex.paintHexagon(g); } } @@ -315,17 +315,35 @@ public abstract class HexMap extends JComponent implements MouseListener, } } - // paint train paths Graphics2D g2 = (Graphics2D) g; - Stroke trainStroke = - new BasicStroke((int)(strokeWidth * zoomFactor), strokeCap, strokeJoin); - g2.setStroke(trainStroke); - - Color[] trainColors = new Color[]{colour1, colour2, colour3, colour4}; - int color = 0; - for (GeneralPath path:trainPaths) { - g2.setColor(trainColors[color++ % trainColors.length]); - g2.draw(path); + + // paint train paths + if (trainPaths != null) { + Stroke oldStroke = g2.getStroke(); + Color oldColor = g2.getColor(); + Stroke trainStroke = + new BasicStroke((int)(strokeWidth * zoomFactor), strokeCap, strokeJoin); + g2.setStroke(trainStroke); + + Color[] trainColors = new Color[]{colour1, colour2, colour3, colour4}; + int color = 0; + for (GeneralPath path:trainPaths) { + g2.setColor(trainColors[color++ % trainColors.length]); + g2.draw(path); + } + g2.setStroke(oldStroke); + g2.setColor(oldColor); + } + + // Paint station tokens only after the train paths + // (so that the path strokes do not hide token information) + for (GUIHex hex : hexes) { + Rectangle hexrect = hex.getBounds(); + + if (g.hitClip(hexrect.x, hexrect.y, hexrect.width, + hexrect.height)) { + hex.paintTokensAndText(g2); + } } } catch (NullPointerException ex) { |