Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BoardTool upgraded to control map image scale #4861

Merged
merged 1 commit into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="net.rptools.maptool.client.tool.boardtool.AdjustBoardControlPanelView">
<grid id="17010" binding="mainPanel" layout-manager="GridLayoutManager" row-count="8" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="17010" binding="mainPanel" layout-manager="GridLayoutManager" row-count="10" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="5" left="5" bottom="5" right="5"/>
<constraints>
<xy x="10" y="10" width="160" height="234"/>
<xy x="10" y="10" width="328" height="307"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="48237" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<name value="snapTitle"/>
Expand Down Expand Up @@ -62,43 +62,45 @@
</component>
<component id="ab54d" class="javax.swing.JLabel">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="net/rptools/maptool/language/i18n" key="GridControlPanel.offset.x"/>
</properties>
</component>
<component id="3cfe1" class="javax.swing.JTextField">
<component id="3b01b" class="javax.swing.JSpinner">
<constraints>
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false">
<minimum-size width="80" height="-1"/>
<preferred-size width="80" height="-1"/>
</grid>
</constraints>
<properties>
<columns value="6"/>
<name value="offsetX"/>
<text value=""/>
</properties>
</component>
<component id="6365a" class="javax.swing.JLabel">
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="net/rptools/maptool/language/i18n" key="GridControlPanel.offset.y"/>
</properties>
</component>
<component id="e163a" class="javax.swing.JTextField">
<component id="f04cb" class="javax.swing.JSpinner">
<constraints>
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false">
<minimum-size width="80" height="-1"/>
<preferred-size width="80" height="-1"/>
</grid>
</constraints>
<properties>
<columns value="6"/>
<name value="offsetY"/>
<text value=""/>
</properties>
</component>
<component id="25ca2" class="javax.swing.JButton">
<constraints>
<grid row="7" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
<grid row="9" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<actionCommand value="Close"/>
Expand All @@ -108,9 +110,49 @@
</component>
<hspacer id="59661">
<constraints>
<grid row="6" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="8" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="17b4f" class="javax.swing.JSpinner" binding="spinner1" default-binding="true">
<constraints>
<grid row="6" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false">
<minimum-size width="80" height="-1"/>
<preferred-size width="80" height="-1"/>
</grid>
</constraints>
<properties>
<name value="sizeX"/>
<toolTipText resource-bundle="net/rptools/maptool/language/i18n" key="AdjustBoardDialog.size.tooltip"/>
</properties>
</component>
<component id="de19b" class="javax.swing.JSpinner" binding="spinner2" default-binding="true">
<constraints>
<grid row="7" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false">
<minimum-size width="80" height="-1"/>
<preferred-size width="80" height="-1"/>
</grid>
</constraints>
<properties>
<name value="sizeY"/>
<toolTipText resource-bundle="net/rptools/maptool/language/i18n" key="AdjustBoardDialog.size.tooltip"/>
</properties>
</component>
<component id="bfae7" class="javax.swing.JLabel">
<constraints>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="net/rptools/maptool/language/i18n" key="AdjustBoardDialog.size.x"/>
</properties>
</component>
<component id="2f82b" class="javax.swing.JLabel">
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="net/rptools/maptool/language/i18n" key="AdjustBoardDialog.size.y"/>
</properties>
</component>
</children>
</grid>
<buttonGroups>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

public class AdjustBoardControlPanelView {
private JPanel mainPanel;
private JSpinner spinner1;
private JSpinner spinner2;

public JComponent getRootComponent() {
return mainPanel;
Expand Down
120 changes: 88 additions & 32 deletions src/main/java/net/rptools/maptool/client/tool/boardtool/BoardTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,19 @@
*/
package net.rptools.maptool.client.tool.boardtool;

import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Point2D;
import java.text.ParseException;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.JTextComponent;
import net.rptools.maptool.client.AppState;
import net.rptools.maptool.client.MapTool;
import net.rptools.maptool.client.ScreenPoint;
Expand All @@ -46,7 +39,8 @@
import net.rptools.maptool.model.drawing.DrawablePaint;
import net.rptools.maptool.model.drawing.DrawableTexturePaint;
import net.rptools.maptool.util.ImageManager;
import net.rptools.maptool.util.StringUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
* Allows user to re-position the background map (internally called the 'board'). This entire class
Expand All @@ -55,13 +49,16 @@
*/
public class BoardTool extends DefaultTool {
private static final long serialVersionUID = 98389912045059L;
private static final Logger log = LogManager.getLogger(BoardTool.class);

// Context variables
private static Zone zone;
private static boolean oldShowGrid;

// Status variables
private static Point boardPosition = new Point(0, 0);
private static Point2D boardSize = new Point2D.Float(1f, 1f);
private static Point2D boardScale = new Point2D.Float(1f, 1f);
private static Dimension snap = new Dimension(1, 1);

// Action control variables
Expand All @@ -70,8 +67,10 @@ public class BoardTool extends DefaultTool {
private Point boardStart;

// UI button fields
private final JTextField boardPositionXTextField;
private final JTextField boardPositionYTextField;
private final JSpinner boardPositionXSpinner;
private final JSpinner boardPositionYSpinner;
private final JSpinner boardSizeXSpinner;
private final JSpinner boardSizeYSpinner;
private final AbeillePanel controlPanel;
private final JRadioButton snapNoneButton;
private final JRadioButton snapGridButton;
Expand All @@ -82,11 +81,21 @@ public BoardTool() {
// Create the control panel
controlPanel = new AbeillePanel(new AdjustBoardControlPanelView().getRootComponent());

boardPositionXTextField = (JTextField) controlPanel.getComponent("offsetX");
boardPositionXTextField.addKeyListener(new UpdateBoardListener());
boardPositionXSpinner = (JSpinner) controlPanel.getComponent("offsetX");
boardPositionXSpinner.setModel(
new SpinnerNumberModel(0, Integer.MIN_VALUE, Integer.MAX_VALUE, 1));
boardPositionXSpinner.addChangeListener(new spinnerListener());

boardPositionYTextField = (JTextField) controlPanel.getComponent("offsetY");
boardPositionYTextField.addKeyListener(new UpdateBoardListener());
boardPositionYSpinner = (JSpinner) controlPanel.getComponent("offsetY");
boardPositionYSpinner.setModel(
new SpinnerNumberModel(0, Integer.MIN_VALUE, Integer.MAX_VALUE, 1));
boardPositionYSpinner.addChangeListener(new spinnerListener());

// getBoardSizing();

boardSizeXSpinner = (JSpinner) controlPanel.getComponent("sizeX");

boardSizeYSpinner = (JSpinner) controlPanel.getComponent("sizeY");

ActionListener enforceRules = evt -> enforceButtonRules();
snapNoneButton = (JRadioButton) controlPanel.getComponent("snapNone");
Expand Down Expand Up @@ -132,6 +141,27 @@ private Dimension getTileSize() {
return tileSize;
}

/** Figure out how big the board image is. */
private void getBoardSizing() {
if (renderer != null) {
boardScale = new Point2D.Float(zone.getImageScaleX(), zone.getImageScaleY());
if (zone.getMapAssetId() != null) {
Image board = ImageManager.getImage(zone.getMapAssetId());
boardSize = new Point2D.Float(board.getWidth(null), board.getHeight(null));

boardSizeXSpinner.setModel(
new SpinnerNumberModel(
boardSize.getX() * boardScale.getX(), Grid.MIN_GRID_SIZE, Integer.MAX_VALUE, 1));
boardSizeYSpinner.setModel(
new SpinnerNumberModel(
boardSize.getY() * boardScale.getY(), Grid.MIN_GRID_SIZE, Integer.MAX_VALUE, 1));

boardSizeXSpinner.addChangeListener(new spinnerListener());
boardSizeYSpinner.addChangeListener(new spinnerListener());
}
}
}

/** Moves the board to the nearest snap intersection. Modifies GUI. */
private void snapBoard() {
boardPosition.x = (Math.round(boardPosition.x / snap.width) * snap.width);
Expand All @@ -152,8 +182,8 @@ private void setSnap(int x, int y) {
}

private void updateGUI() {
boardPositionXTextField.setText(Integer.toString(boardPosition.x));
boardPositionYTextField.setText(Integer.toString(boardPosition.y));
boardPositionXSpinner.setValue(boardPosition.x);
boardPositionYSpinner.setValue(boardPosition.y);
}

/**
Expand All @@ -163,13 +193,16 @@ private void updateGUI() {
private void copyBoardToControlPanel() {
boardPosition.x = zone.getBoardX();
boardPosition.y = zone.getBoardY();
getBoardSizing();
snapBoard();
updateGUI();
}

private void copyControlPanelToBoard() {
boardPosition.x = getInt(boardPositionXTextField, 0);
boardPosition.y = getInt(boardPositionYTextField, 0);
boardPosition.x = (int) boardPositionXSpinner.getModel().getValue();
boardPosition.y = (int) boardPositionYSpinner.getModel().getValue();
zone.setImageScaleX((float) boardScale.getX());
zone.setImageScaleY((float) boardScale.getY());
zone.setBoard(boardPosition);
}

Expand All @@ -183,16 +216,6 @@ public String getInstructions() {
return "tool.boardtool.instructions";
}

/**
* Parses the text field of the component into a number, returning the default value if the text
* field is _not_ a number.
*/
private int getInt(JTextComponent component, int defaultValue) {
// Get the string from the component, then
// call the more-generic getInt-from-a-string
return StringUtil.parseInteger(component.getText(), defaultValue);
}

/*
* private double getDouble(String value, double defaultValue) { try { return value.length() > 0 ? Double.parseDouble(value.trim()) : defaultValue; } catch (NumberFormatException e) { return 0; }
* }
Expand Down Expand Up @@ -353,4 +376,37 @@ private void enforceButtonRules() {
updateGUI();
zone.setBoard(boardPosition);
}

private class spinnerListener implements ChangeListener {
@Override
public void stateChanged(ChangeEvent e) {
JSpinner spinner = (JSpinner) e.getSource();
try {
spinner.commitEdit();
} catch (ParseException pe) {
// Edited value is invalid, revert the spinner to the last valid value,
JComponent editor = spinner.getEditor();
if (editor instanceof JSpinner.DefaultEditor) {
((JSpinner.DefaultEditor) editor).getTextField().setValue(spinner.getValue());
}
}
if (spinner.getName().startsWith("size")) {
updateImageScale(spinner);
}

copyControlPanelToBoard();
}

private void updateImageScale(JSpinner spinner) {
if (spinner.getName().endsWith("X")) {
boardScale.setLocation(
((SpinnerNumberModel) spinner.getModel()).getNumber().floatValue() / boardSize.getX(),
boardScale.getY());
} else {
boardScale.setLocation(
boardScale.getX(),
((SpinnerNumberModel) spinner.getModel()).getNumber().floatValue() / boardSize.getY());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1284,8 +1284,8 @@ protected void renderBoard(Graphics2D g, PlayerView view) {
mapImage,
getViewOffsetX() + (int) (zone.getBoardX() * scaleFactor),
getViewOffsetY() + (int) (zone.getBoardY() * scaleFactor),
(int) (mapImage.getWidth() * scaleFactor),
(int) (mapImage.getHeight() * scaleFactor),
(int) (mapImage.getWidth() * scaleFactor * zone.getImageScaleX()),
(int) (mapImage.getHeight() * scaleFactor * zone.getImageScaleY()),
null);
}
bbg.dispose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,9 @@ AdjustBoardDialog.snapto = Snap to:
AdjustBoardDialog.none.tooltip = No snap.
AdjustBoardDialog.grid.tooltip = Snap to the token grid.
AdjustBoardDialog.tile.tooltip = Snap to the repeating background texture.
AdjustBoardDialog.size.x = Horizontal Size
AdjustBoardDialog.size.y = Vertical Size
AdjustBoardDialog.size.tooltip = Change the size of the image

GridControlPanel.sizeInPixels = Grid Size:
GridControlPanel.sizeInPixels.second = 2nd Size:
Expand Down
Loading