From f87edbb3f88357636d7231bf05c18947609bad73 Mon Sep 17 00:00:00 2001 From: mmyers Date: Sat, 21 May 2022 20:49:38 -0500 Subject: [PATCH] Update positions editor to work with MotE (?) March of the Eagles uses the newer positions format of lists of coordinates, but does not have a built-in nudge tool like other newer games. Hopefully this fixes that gap. --- PositionsEditor/position_types.txt | 95 +++++++++ PositionsEditor/src/posed/EditorDialog.form | 3 +- PositionsEditor/src/posed/EditorDialog.java | 188 ++++++++++++++---- .../src/posed/PositionsEditorUI.form | 2 +- .../src/posed/PositionsEditorUI.java | 55 ++++- PositionsEditor/src/posed/ProvincePanel.form | 3 + PositionsEditor/src/posed/ProvincePanel.java | 109 +++++++--- PositionsEditor/src/posed/Text.java | 2 + 8 files changed, 378 insertions(+), 79 deletions(-) diff --git a/PositionsEditor/position_types.txt b/PositionsEditor/position_types.txt index 4ef5cc1..1281017 100644 --- a/PositionsEditor/position_types.txt +++ b/PositionsEditor/position_types.txt @@ -223,3 +223,98 @@ hoi3 = { } +mote = { + display = "March of the Eagles" + map_inverted = no + has_sea_list = yes + land = { + position = { + garrison_unit/xy + unit/xy + unknown1/xy + unknown2/xy + unknown3/xy + } + rotation = { + garrison_unit/rotation + unit/rotation + unknown1/rotation + unknown2/rotation + unknown3/rotation + } + height = { + garrison_unit/height + unit/height + unknown1/height + unknown2/height + unknown3/height + } + } + sea = {} # don't have any example sea provs to fill this in with +} + + +ck2 = { + display = "Crusader Kings 2" + map_inverted = no + has_sea_list = yes # not accurate, but CK2's sea_zones system isn't implemented in this editor + land = { + position = { + city/xy + unit/xy + councilor/xy + text_position/xy + port/xy + wonder/xy + coastal_wonder/xy + } + rotation = { + city/rotation + unit/rotation + councilor/rotation + text/rotation + port/rotation + wonder/rotation + coastal_wonder/rotation + } + height = { + city/height + unit/height + councilor/height + text/height + port/height + wonder/height + coastal_wonder/height + } + } + sea = { # looks the same as land even though most of the positions aren't used + position = { + city/xy + unit/xy + councilor/xy + text_position/xy + port/xy + wonder/xy + coastal_wonder/xy + } + rotation = { + city/rotation + unit/rotation + councilor/rotation + text/rotation + port/rotation + wonder/rotation + coastal_wonder/rotation + } + height = { + city/height + unit/height + councilor/height + text/height + port/height + wonder/height + coastal_wonder/height + } + } +} + diff --git a/PositionsEditor/src/posed/EditorDialog.form b/PositionsEditor/src/posed/EditorDialog.form index 6604ea3..4fa24b2 100644 --- a/PositionsEditor/src/posed/EditorDialog.form +++ b/PositionsEditor/src/posed/EditorDialog.form @@ -1,4 +1,4 @@ - +
@@ -6,6 +6,7 @@ + diff --git a/PositionsEditor/src/posed/EditorDialog.java b/PositionsEditor/src/posed/EditorDialog.java index fc48695..c4d731b 100644 --- a/PositionsEditor/src/posed/EditorDialog.java +++ b/PositionsEditor/src/posed/EditorDialog.java @@ -6,6 +6,7 @@ package posed; +import eug.shared.GenericList; import eug.shared.GenericObject; import eug.shared.ObjectVariable; import eug.shared.WritableObject; @@ -31,7 +32,11 @@ import java.awt.geom.Rectangle2D; import java.text.DecimalFormat; import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.LinkedHashMap; +import java.util.List; import java.util.Locale; import java.util.logging.Level; import javax.swing.BoxLayout; @@ -52,6 +57,8 @@ public class EditorDialog extends javax.swing.JDialog implements ActionListener, private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(EditorDialog.class.getName()); + private static final String EDIT_BUTTON_TEXT = "Edit..."; + private final MapPanel.ProvinceImage image; private GenericObject originalPositions; private final GenericObject positionTypes; @@ -61,7 +68,7 @@ public class EditorDialog extends javax.swing.JDialog implements ActionListener, private final java.util.Map allFields = new LinkedHashMap<>(); private boolean saveChanges = false; - + // Locale.US ensures that decimal points won't be switched to commas // so we don't get { x = 1.213,500000 y = 694,000000 } private static final NumberFormat sixDigitFormat = NumberFormat.getNumberInstance(Locale.US); @@ -90,7 +97,7 @@ public EditorDialog(java.awt.Frame parent, MapPanel.ProvinceImage image, } initFields(); - setTitle("Editing " + image.getProvName()); + setTitle("Editing " + image.getProvName() + " #" + image.getProvId()); pack(); setLocationRelativeTo(parent); } @@ -131,15 +138,15 @@ private void initFields(JPanel parent, GenericObject positions, GenericObject po container.add(label); if (var.getValue().equalsIgnoreCase("xy")) { - createXYFields(container, positions, var, registry); + createXYFields(container, positions, var.varname, registry); } else if (var.getValue().equalsIgnoreCase("rotation")) { - createRotationField(container, positions, var, false, registry); + createRotationField(container, positions, var.varname, false, registry); } else if (var.getValue().equalsIgnoreCase("reverserotation")) { - createRotationField(container, positions, var, true, registry); + createRotationField(container, positions, var.varname, true, registry); } else if (var.getValue().equalsIgnoreCase("scale")) { - createNonButtonField(container, positions, var, registry); + createNonButtonField(container, positions, var.varname, registry); } else if (var.getValue().equalsIgnoreCase("nudge")) { - createNonButtonField(container, positions, var, registry); + createNonButtonField(container, positions, var.varname, registry); } } else if (wo instanceof GenericObject) { GenericObject obj = (GenericObject) wo; @@ -156,31 +163,107 @@ private void initFields(JPanel parent, GenericObject positions, GenericObject po java.util.Map tmpMap = new java.util.LinkedHashMap<>(); registry.put(obj.name, tmpMap); initFields(subContainer, positions.getChild(obj.name), obj, tmpMap); + } else if (wo instanceof GenericList) { + initListFields((GenericList) wo, positions, registry); } } } - private void createNonButtonField(JPanel parent, GenericObject positions, ObjectVariable var, java.util.Map registry) { + private void initListFields(GenericList defList, GenericObject positions, java.util.Map registry) { + if (defList.size() == 0) + return; + + JPanel container = new JPanel(); + JPanel subContainer = new JPanel(); + subContainer.setLayout(new BoxLayout(subContainer, BoxLayout.Y_AXIS)); + container.add(subContainer); + positionsPane.add(container, toReadableLabel(defList.getName())); + + for (int i = 0; i < defList.size(); i++) { + String[] varNameType = defList.get(i).split("/"); + String varName = varNameType[0]; + String varType = varNameType[1]; + + JPanel fieldContainer = new JPanel(new GridLayout(0, 3, 1, 5)); + fieldContainer.setBorder(new LineBorder(Color.LIGHT_GRAY)); + subContainer.add(fieldContainer); + + JLabel label = new JLabel(toReadableLabel(varName)); + fieldContainer.add(label); + + GenericList positionsList = positions.getList(defList.getName()); + + switch (varType.toLowerCase()) { + case "xy": + createXYFieldsFromList(fieldContainer, positionsList, i, registry); + break; + case "rotation": + createRotationFieldFromList(fieldContainer, positionsList, i, varName, false, registry); + break; + case "reverserotation": + createRotationFieldFromList(fieldContainer, positionsList, i, varName, true, registry); + break; + case "scale": + case "nudge": + default: + createNonButtonFieldFromList(fieldContainer, positionsList, i, registry); + break; + } + } + } + + private void createNonButtonField(JPanel parent, GenericObject positions, String varName, java.util.Map registry) { + String value = (positions != null) ? positions.getString(varName) : null; + JTextField scaleField = doCreateNonButtonField(parent, value); + registry.put(varName, scaleField); + } + + private void createNonButtonFieldFromList(JPanel parent, GenericList positionsList, int index, java.util.Map registry) { + JTextField scaleField = doCreateNonButtonField(parent, positionsList.get(index)); + + // instead of registering the field under its own name, simply add it to the existing registry of the list + @SuppressWarnings("unchecked") + List tmpList = (List) registry.getOrDefault(positionsList.getName(), new ArrayList<>()); + tmpList.add(scaleField); + registry.put(positionsList.getName(), tmpList); + } + + private JTextField doCreateNonButtonField(JPanel parent, String text) { JPanel middlePanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); - final JTextField scaleField = new JTextField(8); - if (positions != null) - scaleField.setText(positions.getString(var.varname)); - middlePanel.add(scaleField); + final JTextField textField = new JTextField(8); + textField.setText(text); + middlePanel.add(textField); parent.add(middlePanel); parent.add(new JPanel()); // to take the JButton's slot + + return textField; + } - registry.put(var.varname, scaleField); + private void createRotationField(JPanel parent, GenericObject positions, final String varName, final boolean reversed, java.util.Map registry) { + String rotation = (positions != null) ? positions.getString(varName) : null; + JTextField rotationField = doCreateRotationField(parent, rotation, reversed, varName); + registry.put(varName, rotationField); } - private void createRotationField(JPanel parent, GenericObject positions, final ObjectVariable var, final boolean reversed, java.util.Map registry) { + private void createRotationFieldFromList(JPanel parent, GenericList positionsList, int index, final String varName, final boolean reversed, java.util.Map registry) { + JTextField rotationField = doCreateRotationField(parent, positionsList.get(index), reversed, varName); + + // instead of registering the field under its own name, simply add it to the existing registry of the list + @SuppressWarnings("unchecked") + List tmpList = (List) registry.getOrDefault(positionsList.getName(), new ArrayList<>()); + tmpList.add(rotationField); + registry.put(positionsList.getName(), tmpList); + } + + private JTextField doCreateRotationField(JPanel parent, String text, boolean reversed, String name) { JPanel middlePanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); final JTextField rotationField = new JTextField(8); - if (positions != null) - rotationField.setText(positions.getString(var.varname)); + if (text != null) + rotationField.setText(text); middlePanel.add(rotationField); parent.add(middlePanel); JPanel rightPanel = new JPanel(); - JButton editButton = new JButton("Edit..."); + JButton editButton = new JButton(EDIT_BUTTON_TEXT); editButton.addActionListener((ActionEvent e) -> { double oldRotation = 0.0; @@ -194,7 +277,7 @@ private void createRotationField(JPanel parent, GenericObject positions, final O } catch (NumberFormatException ex) { } - RotationDialog dialog = new RotationDialog(EditorDialog.this, oldRotation, var.varname); + RotationDialog dialog = new RotationDialog(EditorDialog.this, oldRotation, name); dialog.setVisible(true); double rotation = dialog.getRotation(); @@ -212,11 +295,40 @@ private void createRotationField(JPanel parent, GenericObject positions, final O rightPanel.add(editButton); parent.add(rightPanel); - - registry.put(var.varname, rotationField); + + return rotationField; } - private void createXYFields(JPanel parent, GenericObject positions, ObjectVariable var, java.util.Map registry) { + private void createXYFields(JPanel parent, GenericObject positions, String varName, java.util.Map registry) { + GenericObject position = (positions != null) ? positions.getChild(varName) : null; + String x = (position != null) ? position.getString("x") : null; + String y = (position != null) ? position.getString("y") : null; + List xy = doCreateXYFields(parent, x, y); + + java.util.Map tmpMap = new java.util.LinkedHashMap<>(); + tmpMap.put("x", xy.get(0)); + tmpMap.put("y", xy.get(1)); + registry.put(varName, tmpMap); + } + + private void createXYFieldsFromList(JPanel parent, GenericList positionsList, int index, java.util.Map registry) { + List xy = doCreateXYFields(parent, positionsList.get(index*2), positionsList.get(index*2 + 1)); + + // instead of registering each field under its own name, simply add them to the existing registry of the list + @SuppressWarnings("unchecked") + List tmpList = (List) registry.getOrDefault(positionsList.getName(), new ArrayList<>()); + tmpList.addAll(xy); + registry.put(positionsList.getName(), tmpList); + } + + /** + * Does all the work of creating and laying out a pair of text fields for an X and a Y coordinate. + * @param parent the panel to add the new fields to + * @param xText the text that will initially be in the X text field + * @param yText the text that will initially be in the Y text field + * @return a list consisting of the created X text field and Y text field + */ + private List doCreateXYFields(JPanel parent, String xText, String yText) { JPanel middlePanel = new JPanel(new GridLayout(0, 1)); JPanel xPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 1)); xPanel.add(new JLabel("x")); @@ -226,28 +338,22 @@ private void createXYFields(JPanel parent, GenericObject positions, ObjectVariab yPanel.add(new JLabel("y")); final JTextField yField = new JTextField(7); yPanel.add(yField); - if (positions != null) { - GenericObject position = positions.getChild(var.varname); - if (position != null) { - xField.setText(position.getString("x")); - yField.setText(position.getString("y")); - } - } + + if (xText != null) + xField.setText(xText); + if (yText != null) + yField.setText(yText); + middlePanel.add(xPanel); middlePanel.add(yPanel); parent.add(middlePanel); JPanel rightPanel = new JPanel(); - JButton editButton = new JButton("Edit..."); - editButton.addActionListener((ActionEvent e) -> { - doSetPosition(xField, yField); - }); + JButton editButton = new JButton(EDIT_BUTTON_TEXT); + editButton.addActionListener((ActionEvent e) -> doSetPosition(xField, yField)); rightPanel.add(editButton); parent.add(rightPanel); - - java.util.Map tmpMap = new java.util.LinkedHashMap<>(); - tmpMap.put("x", xField); - tmpMap.put("y", yField); - registry.put(var.varname, tmpMap); + + return Arrays.asList(xField, yField); } /** This method is called from within the constructor to @@ -417,6 +523,14 @@ private void doUpdate(GenericObject positions, java.util.Map obj doUpdate(tmpPos, tmpMap); if (tmpPos.isEmpty()) positions.removeChild(tmpPos); + } else if (entry.getValue() instanceof List) { + @SuppressWarnings("unchecked") + List tmpList = (List) entry.getValue(); + GenericList tmpPos = positions.createList(entry.getKey()); + + for (JTextField t : tmpList) { + tmpPos.add(t.getText(), false); // false = don't put the value in quotes + } } else { log.log(Level.WARNING, "Internal error: Unknown positions value {0}, {1}", new Object[] { entry.getKey(), entry.getValue() }); diff --git a/PositionsEditor/src/posed/PositionsEditorUI.form b/PositionsEditor/src/posed/PositionsEditorUI.form index 0f3d069..c947b43 100644 --- a/PositionsEditor/src/posed/PositionsEditorUI.form +++ b/PositionsEditor/src/posed/PositionsEditorUI.form @@ -136,7 +136,7 @@ - + diff --git a/PositionsEditor/src/posed/PositionsEditorUI.java b/PositionsEditor/src/posed/PositionsEditorUI.java index d998867..c8f5bba 100644 --- a/PositionsEditor/src/posed/PositionsEditorUI.java +++ b/PositionsEditor/src/posed/PositionsEditorUI.java @@ -41,7 +41,7 @@ public class PositionsEditorUI extends javax.swing.JFrame { private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(PositionsEditorUI.class.getName()); - private static final String APP_NAME = "EU3 Positions Editor"; + private static final String APP_NAME = "Positions Editor"; private static final String APP_VERSION = "Beta"; private MapPanel mapPanel; @@ -93,7 +93,7 @@ private void load(String mapFileName, GameVersion gameVersion, boolean useLocali pack(); setLocationRelativeTo(null); - setTitle(APP_NAME + " [" + positionsFile.getPath() + "]"); + setTitle(gameVersion.getDisplay() + " " + APP_NAME + " [" + positionsFile.getPath() + "]"); validateFile(); } @@ -113,7 +113,7 @@ private void initComponents() { mapScrollPane = new javax.swing.JScrollPane(); javax.swing.JPanel jPanel1 = new javax.swing.JPanel(); javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); - provinceList = new javax.swing.JList(); + provinceList = new javax.swing.JList<>(); goToProvButton = new javax.swing.JButton(); javax.swing.JMenuBar menuBar = new javax.swing.JMenuBar(); javax.swing.JMenu fileMenu = new javax.swing.JMenu(); @@ -134,7 +134,7 @@ private void initComponents() { FormListener formListener = new FormListener(); setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); - setTitle(APP_NAME); + setTitle(gameVersion.getDisplay() + " " + APP_NAME); addWindowListener(formListener); jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT); @@ -196,12 +196,12 @@ private void initComponents() { viewMenu.setText("View"); - zoomInMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_EQUALS, java.awt.event.InputEvent.CTRL_MASK)); + zoomInMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_EQUALS, java.awt.event.InputEvent.CTRL_DOWN_MASK)); zoomInMenuItem.setText("Zoom in"); zoomInMenuItem.addActionListener(formListener); viewMenu.add(zoomInMenuItem); - zoomOutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_MINUS, java.awt.event.InputEvent.CTRL_MASK)); + zoomOutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_MINUS, java.awt.event.InputEvent.CTRL_DOWN_MASK)); zoomOutMenuItem.setText("Zoom out"); zoomOutMenuItem.addActionListener(formListener); viewMenu.add(zoomOutMenuItem); @@ -376,7 +376,7 @@ private void saveAsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GE positionsFile = chooser.getSelectedFile(); if (!EUGFileIO.save(positions, positionsFile.getAbsolutePath(), EUGFileIO.NO_COMMENT, true, POSITIONS_STYLE)) JOptionPane.showMessageDialog(this, "Failed to save", "Error", JOptionPane.ERROR_MESSAGE); - setTitle(APP_NAME + " [" + positionsFile.getPath() + "]"); + setTitle(gameVersion.getDisplay() + " " + APP_NAME + " [" + positionsFile.getPath() + "]"); } }//GEN-LAST:event_saveAsMenuItemActionPerformed @@ -548,6 +548,7 @@ else if (tempx == x && tempy == y) private static final GenericObject xy = EUGFileIO.loadFromString("x = double y = double"); private void validateFile() { + log.log(Level.INFO, "Validating positions.txt against the position_types definition..."); for (GenericObject obj : positions.children) { if (mapPanel.getMap().isLand(Integer.parseInt(obj.name))) { validateObject(obj.name, obj, gameVersion.getLand()); @@ -555,6 +556,7 @@ private void validateFile() { validateObject(obj.name, obj, gameVersion.getSea()); } } + log.log(Level.INFO, "Done validating positions.txt"); } private void validateObject(String name, GenericObject positions, GenericObject validation) { @@ -580,7 +582,44 @@ private void validateObject(String name, GenericObject positions, GenericObject log.log(Level.WARNING, "Unknown variable name in {0}: {1}", new Object[]{name, varname}); } } else if (wo instanceof GenericList) { - log.log(Level.WARNING, "Did not expect list: {0}", ((GenericList)wo).getName()); + String listName = ((GenericList) wo).getName(); + GenericList valList = validation.getList(listName); + + if (valList != null) + validateList(name, (GenericList) wo, valList); + else + log.log(Level.WARNING, "Did not expect list: {0}", ((GenericList)wo).getName()); + } + } + } + + /** + * Validates a list of values against a template list. The items in the + * template list must include a slash "/" which separates the entry name + * from the entry data type. For example, the item "port/rotation" in the + * template list will cause the validation to expect a rotation (radian + * value in decimal) in the list being checked. The special data type "/xy" + * causes the validation to expect two values, one each for an X and + * a Y coordinate. + * + * @param objectName the name of the object in which the list is found, for debugging purposes + * @param list + * @param validationList + */ + private void validateList(String objectName, GenericList list, GenericList validationList) { + // Lists must be in a definite order + int i = 0; + for (int j = 0; j < validationList.size(); j++) { + String val = validationList.get(j); + i++; + if (i > list.size()) + log.log(Level.WARNING, "List in province {0} did not have enough elements to match the validation: {1}", new Object[]{ objectName, list.getName() }); + + if (val.contains("/")) { + String[] valSplit = val.split("/"); + String valType = valSplit[1]; + if (valType.equals("xy")) + i++; // expect two list elements for an X/Y coordinate pair } } } diff --git a/PositionsEditor/src/posed/ProvincePanel.form b/PositionsEditor/src/posed/ProvincePanel.form index 4d00c4f..73ae29b 100644 --- a/PositionsEditor/src/posed/ProvincePanel.form +++ b/PositionsEditor/src/posed/ProvincePanel.form @@ -3,12 +3,15 @@ + + + diff --git a/PositionsEditor/src/posed/ProvincePanel.java b/PositionsEditor/src/posed/ProvincePanel.java index 838c472..4b849be 100644 --- a/PositionsEditor/src/posed/ProvincePanel.java +++ b/PositionsEditor/src/posed/ProvincePanel.java @@ -6,6 +6,7 @@ package posed; +import eug.shared.GenericList; import eug.shared.GenericObject; import eug.shared.ObjectVariable; import java.awt.Color; @@ -131,6 +132,39 @@ private void drawIcons(Graphics2D g2d, GenericObject positions, GenericObject po for (GenericObject obj : positionTypes.children) { drawIcons(g2d, positions.getChild(obj.name), obj); } + if (positions != null && !positions.lists.isEmpty()) { + if (positionTypes.containsList("position") && positionTypes.containsList("rotation")) { + drawIconsFromList(g2d, positions.getList("position"), positions.getList("rotation"), positionTypes.getList("position")); + } + } + } + + private void drawIconsFromList(Graphics2D g2d, GenericList positions, GenericList rotations, GenericList positionTypes) { + // Lists must be in a definite order + // If we have a list of x/y coordinates and a list of rotations, try to match them + int i = 0; + for (int j = 0; j < positionTypes.size(); j++) { + String positionType = positionTypes.get(j); + String value = positions.get(i); + i++; + if (i >= positions.size()) + log.log(Level.WARNING, "List did not have enough elements to match the validation: {0}", positions.getName()); + + if (positionType.contains("/")) { + String[] valSplit = positionType.split("/"); + String valType = valSplit[1]; + if (valType.equals("xy")) { + // expect two list elements for an X/Y coordinate pair + String val2 = positions.get(i); + i++; + + float x = translateX(Float.parseFloat(value)); + float y = translateY(Float.parseFloat(val2)); + double rotation = Double.parseDouble(rotations.get(j)); // j, not i, since i increments twice for every position type + drawLocation(valSplit[0], g2d, rotation, 0.0, x, y); + } + } + } } private void drawLocationIfPossible(String name, Graphics2D g, GenericObject positions) { @@ -144,50 +178,61 @@ private void drawLocationIfPossible(String name, Graphics2D g, GenericObject pos float x = translateX(temp.getDouble("x")); float y = translateY(temp.getDouble("y")); + + drawLocation(name, g, rotation, locScale, x, y); + } + } + + private void drawLocation(String name, Graphics2D g, double rotation, double locScale, float x, float y) { - Font oldFont = null; - if (locScale > 0.0) { - oldFont = g.getFont(); - float fontSize = (float) (this.scale * ourScale * locScale); + Font oldFont = null; + if (locScale > 0.0) { + oldFont = g.getFont(); + float fontSize = (float) (this.scale * ourScale * locScale); // if (fontSize < 6.0f) // fontSize = 6.0f; // else if (fontSize > 24.) - g.setFont(oldFont.deriveFont(fontSize)); + g.setFont(oldFont.deriveFont(fontSize)); + } else { + Font f = g.getFont(); + if (f.getSize() < 10) { + oldFont = g.getFont(); + g.setFont(oldFont.deriveFont(10.0f)); } + } - Rectangle2D rect = g.getFontMetrics().getStringBounds(image.getProvName(), g); - - AffineTransform at = null; - AffineTransform oldTx = null; + Rectangle2D rect = g.getFontMetrics().getStringBounds(image.getProvName(), g); - if (rotation != -1.0) { - // at = AffineTransform.getTranslateInstance(x - (rect.getWidth()/2), y - (rect.getHeight()/2)); - at = AffineTransform.getTranslateInstance(x, y); - at.rotate(-rotation); - oldTx = g.getTransform(); - g.transform(at); - } + AffineTransform at = null; + AffineTransform oldTx = null; - String text = (name.equalsIgnoreCase("text_position") ? image.getProvName() : name); - if (at != null) { - g.drawString(text, -(int) (rect.getWidth()/2), 0); - } else { - g.drawString(text, x - (int) (rect.getWidth()/2), y + (int) (rect.getHeight()/2)); - } + if (rotation != -1.0 && rotation != 0.0) { +// at = AffineTransform.getTranslateInstance(x - (rect.getWidth()/2), y - (rect.getHeight()/2)); + at = AffineTransform.getTranslateInstance(x, y); + at.rotate(-rotation); + oldTx = g.getTransform(); + g.transform(at); + } - if (rotation > 0.0) { - g.setTransform(oldTx); - } + String text = (name.equalsIgnoreCase("text_position") ? image.getProvName() : name); + if (at != null) { + g.drawString(text, -(int) (rect.getWidth()/2), 0); + } else { + g.drawString(text, x - (int) (rect.getWidth()/2), y + (int) (rect.getHeight()/2)); + } - if (locScale > 0.0) { - g.setFont(oldFont); - } + if (oldTx != null) { + g.setTransform(oldTx); + } - Paint old = g.getPaint(); - g.setColor(DOT_COLORS[(colorIdx++) % DOT_COLORS.length]); - g.fillOval((int) x - 3, (int) y - 3, 6, 6); - g.setPaint(old); + if (oldFont != null) { + g.setFont(oldFont); } + + Paint old = g.getPaint(); + g.setColor(DOT_COLORS[(colorIdx++) % DOT_COLORS.length]); + g.fillOval((int) x - 3, (int) y - 3, 6, 6); + g.setPaint(old); } private void drawText(Graphics2D g) { diff --git a/PositionsEditor/src/posed/Text.java b/PositionsEditor/src/posed/Text.java index 83a5f43..a89ff48 100644 --- a/PositionsEditor/src/posed/Text.java +++ b/PositionsEditor/src/posed/Text.java @@ -72,6 +72,8 @@ private static void initTextFromFolder(File locFolder) throws FileNotFoundExcept if (firstSemi < 0 || secondSemi < 0) { log.log(Level.WARNING, "Malformed line in file {0}:\n{1}", new Object[]{f.getPath(), line}); } + if (secondSemi < 0) + secondSemi = line.length() - 1; String key = line.substring(0, firstSemi).toLowerCase(); if (!text.containsKey(key)) text.put(key, line.substring(firstSemi + 1, secondSemi));