diff --git a/src/main/java/net/rptools/maptool/client/AppPreferences.java b/src/main/java/net/rptools/maptool/client/AppPreferences.java index b42ea6471e..c50ca19f71 100644 --- a/src/main/java/net/rptools/maptool/client/AppPreferences.java +++ b/src/main/java/net/rptools/maptool/client/AppPreferences.java @@ -29,38 +29,131 @@ import net.rptools.maptool.client.walker.WalkerMetric; import net.rptools.maptool.language.I18N; import net.rptools.maptool.model.GridFactory; +import net.rptools.maptool.model.Label; import net.rptools.maptool.model.Token; import net.rptools.maptool.model.Zone; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +/** The AppPreferences class is used for managing the preferences of the application. */ public class AppPreferences { + /** + * The log variable represents a logger object used for logging messages in the AppPreferences + * class. It is a private static final variable of type Logger. The logger object is obtained + * using the getLogger method from the LogManager class, specifying the AppPreferences class as + * the logging context. + */ private static final Logger log = LogManager.getLogger(AppPreferences.class); + + /** + * This private static variable represents the user preferences node for the application. It is an + * instance of the Preferences class, which provides a way to store and retrieve user preferences + * using a hierarchical tree of preference nodes, starting from the user root node. + * + *

The preferences are stored under a specific node path derived from the application name + * using the AppConstants.APP_NAME constant. + * + *

This variable is used to access and modify user preferences throughout the application. + */ private static Preferences prefs = Preferences.userRoot().node(AppConstants.APP_NAME + "/prefs"); + /** Holds the render quality preference setting for the application. */ private static RenderQuality renderQuality; + /** + * Defines the key constant for retrieving asset roots. + * + *

This constant is used to define the key for accessing asset roots in a configuration file or + * a data source. Asset roots represent the directories or paths where application assets are + * stored. + * + *

The asset roots can be used to locate and load files, images, or other resources required by + * the application at runtime. By convention, the asset root directories are organized in a + * structured manner to facilitate easy retrieval of assets. + */ private static final String KEY_ASSET_ROOTS = "assetRoots"; + + /** + * The constant representing the key for the save directory. + * + *

This key is used to access and store the value of the save directory. The value associated + * with this key should be a string representing the directory path. + */ private static final String KEY_SAVE_DIR = "saveDir"; + + /** + * The constant representing the key for saving token directory. This constant is used to retrieve + * the directory path where token information will be exported. + */ private static final String KEY_SAVE_TOKEN_DIR = "saveTokenDir"; + + /** + * The variable to store the key for saving the map directory. + * + *

This variable is used to configure the directory where the map will be export. + */ private static final String KEY_SAVE_MAP_DIR = "saveMapDir"; + + /** + * The key for the load directory. + * + *

This constant represents the key used to specify the last directory used for loading files + * so that subsequent dialogs will be opened with the same path. + * + *

The value should be a String representing the directory path. + */ private static final String KEY_LOAD_DIR = "loadDir"; + + /** + * The configuration key for specifying the directory path where the last add-on was loaded from, + * so that subsequent dialogs will be opened with the same path. + * + *

The value should be a String representing the directory path. + */ private static final String KEY_ADD_ON_LOAD_DIR = "addOnLoadDir"; + + /** Represents the key used to access the most recently used campaigns for the menu option. */ private static final String KEY_MRU_CAMPAIGNS = "mruCampaigns"; + + /** Represents the key used to save the paint textures to the preferences. */ private static final String KEY_SAVED_PAINT_TEXTURES = "savedTextures"; + /** + * Represents the key used to determine if the user should be prompted to save the campaign on + * quit. + */ private static final String KEY_SAVE_REMINDER = "autoSaveReminder"; + + /** + * The default value for the {@code KEY_SAVE_REMINDER} key. + * + * @see #KEY_SAVE_REMINDER + */ private static final boolean DEFAULT_SAVE_REMINDER = true; + /** + * Represents the key for the method used to determine which name of the token (Player/GM) the + * number is appended to. + */ private static final String KEY_TOKEN_NUMBER_DISPLAY = "tokenNumberDisplayg"; + + /** + * The default value for the {@code KEY_TOKEN_NUMBER_DISPLAY} preference option,. + * + * @see #KEY_TOKEN_NUMBER_DISPLAY + */ private static final String DEFAULT_TOKEN_NUMBER_DISPLAY = Token.NUM_ON_NAME; + /** Represents the key used to retrieve the number of minutes between auto saves. */ private static final String KEY_AUTO_SAVE_INCREMENT = "autoSaveIncrement"; - private static final int DEFAULT_AUTO_SAVE_INCREMENT = 5; // Minutes - // private static final String KEY_ENABLE_MAP_EXPORT_IMPORT = "enableMapExportImport"; - // private static final boolean DEFAULT_ENABLE_MAP_EXPORT_IMPORT = false; + /** + * The default value for the {@code KEY_AUTO_SAVE_INCREMENT} preference option. + * + * @see #KEY_AUTO_SAVE_INCREMENT + */ + private static final int DEFAULT_AUTO_SAVE_INCREMENT = 5; // Minutes private static final String KEY_CHAT_AUTOSAVE_TIME = "chatAutosaveTime"; private static final int DEFAULT_CHAT_AUTOSAVE_TIME = 0; // Minutes; zero=disabled @@ -449,6 +542,128 @@ public static int getFogOverlayOpacity() { private static final String KEY_PLAY_STREAMS = "playStreams"; private static final boolean DEFAULT_PLAY_STREAMS = true; + /** + * The key for retrieving the background color of NPC map labels. The value of this key is used to + * store and retrieve background color information for NPC map The background color is used to + * style the text of the map labels for Non-Player Characters (NPCs). labels. The value associated + * with this key should be a valid color value. + */ + private static final String KEY_NPC_MAP_LABEL_BG_COLOR = "npcMapLabelBG"; + + /** + * Constant variable for the foreground color of NPC map labels. The value represents the key used + * to retrieve the color from a map or configuration file. The foreground color is used to style + * the text of the map labels for Non-Player Characters (NPCs). This constant is intended to be + * used within the context of a software application or system. + */ + private static final String KEY_NPC_MAP_LABEL_FG_COLOR = "npcMapLabelFG"; + + /** + * Constant variable for the border color of NPC map labels. The value represents the key used to + * retrieve the color from a map or configuration file. The foreground color is used to style the + * text of the map labels for Non-Player Characters (NPCs). This constant is intended to be used + * within the context of a software application or system. + */ + private static final String KEY_NPC_MAP_LABEL_BORDER_COLOR = "mapLabelBorderColor"; + + /** + * The key for retrieving the background color of PC map labels. The value of this key is used to + * store and retrieve background color information for NPC map The background color is used to + * style the text of the map labels for Player Characters (PCs) labels. The value associated with + * this key should be a valid color value. + */ + private static final String KEY_PC_MAP_LABEL_BG_COLOR = "pcMapLabelBG"; + + /** + * Constant variable for the foreground color of NPC map labels. The value represents the key used + * to retrieve the color from a map or configuration file. The border color is used to style the + * text of the map labels for Non Player Characters (NPCs). + */ + private static final String KEY_PC_MAP_LABEL_FG_COLOR = "pcMapLabelFG"; + + /** + * Constant variable for the foreground color of PC map labels. The value represents the key used + * to retrieve the color from a map or configuration file. The border color is used to style the + * text of the map labels for Player Characters (PCs). + */ + private static final String KEY_PC_MAP_LABEL_BORDER_COLOR = "pcMapLabelBorderColor"; + + /** + * This variable represents the key used to store the background color of non-visible token map + * labels. The background color is used to style the text of the map labels for tokens that are + * not visible to the player. The value associated with this key should be a valid color value. + */ + private static final String KEY_NONVIS_MAP_LABEL_BG_COLOR = "nonVisMapLabelBG"; + + /** + * This variable represents the key used to store the foreground color of non-visible token map + * labels. The foreground color is used to style the text of the map labels for tokens that are + * not visible to the player. The value associated with this key should be a valid color value. + */ + private static final String KEY_NONVIS_MAP_LABEL_FG_COLOR = "nonVisMapLabelFG"; + + /** + * This variable represents the key used to store the border color of non-visible token map + * labels. The foreground color is used to style the text of the map labels for tokens that are + * not visible to the player. The value associated with this key should be a valid color value. + */ + private static final String KEY_NONVIS_MAP_LABEL_BORDER_COLOR = "nonVisMapLabelBorderColor"; + + /** + * The KEY_MAP_LABEL_FONT_SIZE constant is used to define the name of the key that represents the + * font size of map labels. + */ + private static final String KEY_MAP_LABEL_FONT_SIZE = "mapLabelFontSize"; + + /** The configuration key for specifying the width of the border around map labels for tokens. */ + private static final String KEY_MAP_LABEL_BORDER_WIDTH = "mapLabelBorderWidth"; + + /** The configuration key for specifying the arc of the border around map labels for tokens. */ + private static final String KEY_MAP_LABEL_BORDER_ARC = "mapLabelBorderArc"; + + /** The configuration key for specifying the width of the border around map labels for tokens. */ + private static final String KEY_MAP_LABEL_SHOW_BORDER = "mapLabelShowBorder"; + + /** The default background color for the NPC map label. */ + private static final Color DEFAULT_NPC_MAP_LABEL_BG_COLOR = Color.LIGHT_GRAY; + + /** The default foreground color for NPC map labels. */ + private static final Color DEFAULT_NPC_MAP_LABEL_FG_COLOR = Color.BLACK; + + /** The default border color for NPC map labels. */ + private static final Color DEFAULT_NPC_MAP_LABEL_BORDER_COLOR = DEFAULT_NPC_MAP_LABEL_FG_COLOR; + + /** The default background color for the PC map label. */ + private static final Color DEFAULT_PC_MAP_LABEL_BG_COLOR = Color.WHITE; + + /** The default foreground color for the map labels in the PC map. */ + private static final Color DEFAULT_PC_MAP_LABEL_FG_COLOR = Color.BLUE; + + /** The default border color for the PC map labels. */ + private static final Color DEFAULT_PC_MAP_LABEL_BORDER_COLOR = DEFAULT_PC_MAP_LABEL_FG_COLOR; + + /** The default background color for non-visible map labels. */ + private static final Color DEFAULT_NONVIS_MAP_LABEL_BG_COLOR = Color.BLACK; + + /** The default foreground color for non-visible map labels. */ + private static final Color DEFAULT_NONVIS_MAP_LABEL_FG_COLOR = Color.WHITE; + + /** The default border color for non-visible map labels. */ + private static final Color DEFAULT_NONVIS_MAP_LABEL_BORDER_COLOR = + DEFAULT_NONVIS_MAP_LABEL_FG_COLOR; + + /** The default font size for map labels. */ + private static final int DEFAULT_MAP_LABEL_FONT_SIZE = AppStyle.labelFont.getSize(); + + /** The default border width for token map labels. */ + private static final int DEFAULT_MAP_LABEL_BORDER_WIDTH = Label.DEFAULT_LABEL_BORDER_WIDTH; + + /** The default border arc for token map labels. */ + private static final int DEFAULT_MAP_LABEL_BORDER_ARC = Label.DEFAULT_LABEL_BORDER_ARC; + + /** The default border arc for token map labels. */ + private static final boolean DEFAULT_MAP_LABEL_SHOW_BORDER = true; + public static void setHaloLineWidth(int size) { prefs.putInt(KEY_HALO_LINE_WIDTH, size); } @@ -541,8 +756,6 @@ public static int getHaloLineWidth() { private static final String KEY_RENDER_QUALITY = "renderScaleQuality"; - private static final RenderQuality DEFAULT_RENDER_QUALITY = RenderQuality.LOW_SCALING; - public enum RenderQuality { LOW_SCALING, PIXEL_ART_SCALING, @@ -609,9 +822,9 @@ public static RenderQuality getRenderQuality() { if (renderQuality == null) { try { renderQuality = - RenderQuality.valueOf(prefs.get(KEY_RENDER_QUALITY, DEFAULT_RENDER_QUALITY.name())); + RenderQuality.valueOf(prefs.get(KEY_RENDER_QUALITY, RenderQuality.LOW_SCALING.name())); } catch (Exception e) { - renderQuality = DEFAULT_RENDER_QUALITY; + renderQuality = RenderQuality.LOW_SCALING; } } return renderQuality; @@ -1478,4 +1691,254 @@ public static void setTopologyTypes(Zone.TopologyTypeSet types) { prefs.put(KEY_TOPOLOGY_TYPES, types.toString()); } } + + /** + * Returns the background color to use for NPC Map Labels. + * + * @return the background color to use for NPC Map Labels. + */ + public static Color getNPCMapLabelBG() { + return new Color( + prefs.getInt(KEY_NPC_MAP_LABEL_BG_COLOR, DEFAULT_NPC_MAP_LABEL_BG_COLOR.getRGB()), true); + } + + /** + * Sets the background color to use for NPC Map Labels. + * + * @param color the background color to use for NPC Map Labels. + */ + public static void setNPCMapLabelBG(Color color) { + prefs.putInt(KEY_NPC_MAP_LABEL_BG_COLOR, color.getRGB()); + } + + /** + * Returns the border color to use for PC Map Labels. + * + * @return the border color to use for PC Map Labels. + */ + public static Color getPCMapLabelBorder() { + return new Color( + prefs.getInt(KEY_PC_MAP_LABEL_BORDER_COLOR, DEFAULT_PC_MAP_LABEL_BORDER_COLOR.getRGB()), + true); + } + + /** + * Sets the border color to use for PC Map Labels. + * + * @param color the border color to use for PC Map Labels. + */ + public static void setPCMapLabelBorder(Color color) { + prefs.putInt(KEY_PC_MAP_LABEL_BORDER_COLOR, color.getRGB()); + } + + /** + * Returns the foreground color to use for NPC Map Labels. + * + * @return the foreground color to use for NPC Map Labels. + */ + public static Color getNPCMapLabelFG() { + return new Color( + prefs.getInt(KEY_NPC_MAP_LABEL_FG_COLOR, DEFAULT_NPC_MAP_LABEL_FG_COLOR.getRGB()), true); + } + + /** + * Sets the foreground color to use for NPC Map Labels. + * + * @param color the foreground color to use for NPC Map Labels. + */ + public static void setNPCMapLabelFG(Color color) { + prefs.putInt(KEY_NPC_MAP_LABEL_FG_COLOR, color.getRGB()); + } + + /** + * Returns the border color to use for NPC Map Labels. + * + * @return the border color to use for NPC Map Labels. + */ + public static Color getNPCMapLabelBorder() { + return new Color( + prefs.getInt(KEY_NPC_MAP_LABEL_BORDER_COLOR, DEFAULT_NPC_MAP_LABEL_BORDER_COLOR.getRGB()), + true); + } + + /** + * Sets the border color to use for NPC Map Labels. + * + * @param color the border color to use for NPC Map Labels. + */ + public static void setNPCMapLabelBorder(Color color) { + prefs.putInt(KEY_NPC_MAP_LABEL_BORDER_COLOR, color.getRGB()); + } + + /** + * Returns the background color to use for PC Map Labels. + * + * @return the background color to use for PC Map Labels. + */ + public static Color getPCMapLabelBG() { + return new Color( + prefs.getInt(KEY_PC_MAP_LABEL_BG_COLOR, DEFAULT_PC_MAP_LABEL_BG_COLOR.getRGB()), true); + } + + /** + * Sets the background color to use for PC Map Labels. + * + * @param color the background color to use for PC Map Labels. + */ + public static void setPCMapLabelBG(Color color) { + prefs.putInt(KEY_PC_MAP_LABEL_BG_COLOR, color.getRGB()); + } + + /** + * Returns the foreground color to use for PC Map Labels. + * + * @return the foreground color to use for PC Map Labels. + */ + public static Color getPCMapLabelFG() { + return new Color( + prefs.getInt(KEY_PC_MAP_LABEL_FG_COLOR, DEFAULT_PC_MAP_LABEL_FG_COLOR.getRGB()), true); + } + + /** + * Sets the foreground color to use for PC Map Labels. + * + * @param color the foreground color to use for PC Map Labels. + */ + public static void setPCMapLabelFG(Color color) { + prefs.putInt(KEY_PC_MAP_LABEL_FG_COLOR, color.getRGB()); + } + + /** + * Returns the background color to use for Non-Visible Token Map Labels. + * + * @return the background color to use for Non-Visible Token Map Labels. + */ + public static Color getNonVisMapLabelBG() { + return new Color( + prefs.getInt(KEY_NONVIS_MAP_LABEL_BG_COLOR, DEFAULT_NONVIS_MAP_LABEL_BG_COLOR.getRGB()), + true); + } + + /** + * Sets the background color to use for Non-Visible Token Map Labels. + * + * @param color the background color to use for Non-Visible Token Map Labels. + */ + public static void setNonVisMapLabelBG(Color color) { + prefs.putInt(KEY_NONVIS_MAP_LABEL_BG_COLOR, color.getRGB()); + } + + /** + * Returns the foreground color to use for Non-Visible Token Map Labels. + * + * @return the foreground color to use for Non-Visible Token Map Labels. + */ + public static Color getNonVisMapLabelFG() { + return new Color( + prefs.getInt(KEY_NONVIS_MAP_LABEL_FG_COLOR, DEFAULT_NONVIS_MAP_LABEL_FG_COLOR.getRGB()), + true); + } + + /** + * Sets the foreground color to use for Non-Visible Token Map Labels. + * + * @param color the foreground color to use for Non-Visible Token Map Labels. + */ + public static void setNonVisMapLabelFG(Color color) { + prefs.putInt(KEY_NONVIS_MAP_LABEL_FG_COLOR, color.getRGB()); + } + + /** + * Returns the border color to use for Non-Visible Token Map Labels. + * + * @return the border color to use for Non-Visible Token Map Labels. + */ + public static Color getNonVisMapLabelBorder() { + return new Color( + prefs.getInt( + KEY_NONVIS_MAP_LABEL_BORDER_COLOR, DEFAULT_NONVIS_MAP_LABEL_BORDER_COLOR.getRGB()), + true); + } + + /** + * Sets the border color to use for Non-Visible Token Map Labels. + * + * @param color the border color to use for Non-Visible Token Map Labels. + */ + public static void setNonVisMapLabelBorder(Color color) { + prefs.putInt(KEY_NONVIS_MAP_LABEL_BORDER_COLOR, color.getRGB()); + } + + /** + * Returns the font size to use for Map Token Labels. + * + * @return the font size to use for Map Token Labels. + */ + public static int getMapLabelFontSize() { + return prefs.getInt(KEY_MAP_LABEL_FONT_SIZE, DEFAULT_MAP_LABEL_FONT_SIZE); + } + + /** + * Sets the font size to use for Map Token Labels. + * + * @param size the font size to use for Map Token Labels. + */ + public static void setMapLabelFontSize(int size) { + prefs.putInt(KEY_MAP_LABEL_FONT_SIZE, size); + } + + /** + * Gets the width of the border for token map labels. + * + * @return The width of the border for map labels. + */ + public static int getMapLabelBorderWidth() { + return prefs.getInt(KEY_MAP_LABEL_BORDER_WIDTH, DEFAULT_MAP_LABEL_BORDER_WIDTH); + } + + /** + * Sets the width of the border for token map labels. + * + * @param width the width of the border in pixels + */ + public static void setMapLabelBorderWidth(int width) { + prefs.putInt(KEY_MAP_LABEL_BORDER_WIDTH, width); + } + + /** + * Returns the value of the preference for the map label border arc. + * + * @return the value of the preference for the map label border arc + */ + public static int getMapLabelBorderArc() { + return prefs.getInt(KEY_MAP_LABEL_BORDER_ARC, DEFAULT_MAP_LABEL_BORDER_ARC); + } + + /** + * Sets the value of the preference for the map label border arc. + * + * @param arc the value of the preference for the map label border arc + */ + public static void setMapLabelBorderArc(int arc) { + prefs.putInt(KEY_MAP_LABEL_BORDER_ARC, arc); + } + + /** + * Returns the value of the preference "show map label border". The preference determines whether + * the border should be shown around the map label or not. + * + * @return {@code true} if the map label border should be shown, {@code false} otherwise. + */ + public static boolean getShowMapLabelBorder() { + return prefs.getBoolean(KEY_MAP_LABEL_SHOW_BORDER, DEFAULT_MAP_LABEL_SHOW_BORDER); + } + + /** + * Sets the preference for showing or hiding the border of map labels. + * + * @param show {@code true} to show the border, {@code false} to hide the border + */ + public static void setShowMapLabelBorder(boolean show) { + prefs.putBoolean(KEY_MAP_LABEL_SHOW_BORDER, show); + } } diff --git a/src/main/java/net/rptools/maptool/client/swing/label/FlatImageLabel.java b/src/main/java/net/rptools/maptool/client/swing/label/FlatImageLabel.java new file mode 100644 index 0000000000..8234ddd804 --- /dev/null +++ b/src/main/java/net/rptools/maptool/client/swing/label/FlatImageLabel.java @@ -0,0 +1,211 @@ +/* + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. + * + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . + */ +package net.rptools.maptool.client.swing.label; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.geom.RoundRectangle2D; +import javax.swing.SwingUtilities; + +/** + * The FlatImageLabel class represents an image label with customizable properties such as padding, + * colors, font, and justification. It can be used to create labels for images in various + * containers. + */ +public class FlatImageLabel { + + /** + * The Justification enum represents the different types of text justification. It can be used to + * align text to the left, right, or center of a container. + */ + public enum Justification { + /** The text is aligned to the left of the container. */ + Left, + /** The text is aligned to the right of the container. */ + Right, + /** The text is aligned to the center of the container. */ + Center + } + + /** + * The padX variable represents the amount of padding to be added horizontally to the text in a + * FlatImageLabel object. + * + *

This value is used in the getDimensions() and render() methods of the FlatImageLabel class + * to calculate the width and positioning of the rendered text. + * + *

The padding is added on both sides of the text, resulting in a wider width of the label. It + * ensures that the text is not rendered too close to the edges of the label, providing better + * visual aesthetics. + * + *

The padX value should be a non-negative integer, representing the number of pixels of + * padding. A higher value will result in greater horizontal spacing between the text and the + * edges of the label. + * + * @see FlatImageLabel#getDimensions(Graphics2D, String) + * @see FlatImageLabel#render(Graphics2D, int, int, String) + */ + private final int padX; + + /** + * The private final integer padY represents the vertical padding value for a FlatImageLabel. It + * specifies the amount of empty space (in pixels) to be added above and below the text or image + * within the label. + * + *

This value is set during the initialization of a FlatImageLabel object, using the padY + * parameter of the constructor. Once set, the padY value cannot be changed. + * + *

The padY value should be a non-negative integer, representing the number of pixels of + * padding. A higher value will result in greater vertical spacing between the text and the edges + * of the label. + * + * @see FlatImageLabel#getDimensions(Graphics2D, String) + * @see FlatImageLabel#render(Graphics2D, int, int, String) + */ + private final int padY; + + /** The background variable represents the color used as the background of a FlatImageLabel. */ + private final Color background; + + /** + * The foreground variable holds the color value for the foreground of a FlatImageLabel object. + */ + private final Color foreground; + + /** + * The private final variable 'font' represents the font used for rendering text in the + * FlatImageLabel class. + */ + private final Font font; + + /** + * The Justification enum represents the different types of text justification. It can be used to + * align text to the left, right, or center of a container. + */ + private final Justification justification; + + /** The borderColor variable represents the color used as the border of a FlatImageLabel. */ + private final Color borderColor; + + /** The borderSize variable represents the size of the border for a FlatImageLabel. */ + private final int borderWidth; + + /** The borderArc variable represents the size of the border arc for a FlatImageLabel. */ + private final int borderArc; + + /** + * The FlatImageLabel class represents an image label with customizable properties such as + * padding, colors, font, and justification. It can be used to create labels for images in various + * containers. + * + * @param padX the horizontal padding value for the label. + * @param padY the vertical padding value for the label. + * @param foreground the color value for the foreground of the label. + * @param background the color value for the background of the label. + * @param borderColor the color value for the border of the label. + * @param font the font used for rendering text in the label. + * @param justification the type of text justification used for the label. + * @param borderWidth the size of the border for the label. + */ + public FlatImageLabel( + int padX, + int padY, + Color foreground, + Color background, + Color borderColor, + Font font, + Justification justification, + int borderWidth, + int borderArc) { + this.padX = padX; + this.padY = padY; + this.foreground = foreground; + this.background = background; + this.font = font; + this.justification = justification; + this.borderColor = borderColor; + this.borderWidth = borderWidth; + this.borderArc = borderArc; + } + + /** + * Calculates the dimensions required to display the given string using the specified graphics + * context. + * + * @param graphics2D the graphics context used for rendering + * @param string the string to be displayed + * @return the dimensions required to display the string with padding + */ + public Dimension getDimensions(Graphics2D graphics2D, String string) { + var g2d = (Graphics2D) graphics2D.create(); + g2d.setFont(font); + var fm = g2d.getFontMetrics(); + int strWidth = SwingUtilities.computeStringWidth(fm, string); + int strHeight = fm.getHeight(); + return new Dimension( + strWidth + padX * 2 + borderWidth * 2, strHeight + padY * 2 + borderWidth * 2); + } + + /** + * Renders a string with customizable properties such as font, padding, colors, and justification + * using the specified graphics context. + * + * @param graphics2D the graphics context used for rendering + * @param x the x-coordinate of the top-left corner of the rendered string + * @param y the y-coordinate of the top-left corner of the rendered string + * @param string the string to be rendered + * @return a Rectangle representing the dimensions and position of the rendered string with + * padding + */ + public Rectangle render(Graphics2D graphics2D, int x, int y, String string) { + var g2d = (Graphics2D) graphics2D.create(); + g2d.setFont(font); + var fm = g2d.getFontMetrics(); + int strWidth = SwingUtilities.computeStringWidth(fm, string); + int strHeight = fm.getAscent() - fm.getDescent() - fm.getLeading(); + + var dim = getDimensions(g2d, string); + int width = (int) dim.getWidth(); + int height = (int) dim.getHeight(); + + var bounds = new Rectangle(x, y, width, height); + + int stringY = y + height / 2 + strHeight / 2; + int stringX = + switch (justification) { + case Left -> x + padY; + case Right -> width - strWidth - padX; + case Center -> x + padX + (width - strWidth) / 2 - padX; + }; + + var labelRect = new RoundRectangle2D.Float(x, y, width - 1, height - 1, borderArc, borderArc); + g2d.setBackground(background); + g2d.setColor(background); + g2d.fill(labelRect); + g2d.setColor(foreground); + g2d.drawString(string, stringX, stringY); + if (borderWidth > 0) { + g2d.setStroke(new BasicStroke(borderWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + g2d.setColor(borderColor); + g2d.draw(labelRect); + } + + return bounds; + } +} diff --git a/src/main/java/net/rptools/maptool/client/swing/label/FlatImageLabelFactory.java b/src/main/java/net/rptools/maptool/client/swing/label/FlatImageLabelFactory.java new file mode 100644 index 0000000000..79cfe5f2e3 --- /dev/null +++ b/src/main/java/net/rptools/maptool/client/swing/label/FlatImageLabelFactory.java @@ -0,0 +1,129 @@ +/* + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. + * + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . + */ +package net.rptools.maptool.client.swing.label; + +import java.awt.Color; +import net.rptools.maptool.client.AppPreferences; +import net.rptools.maptool.client.AppStyle; +import net.rptools.maptool.client.swing.label.FlatImageLabel.Justification; +import net.rptools.maptool.model.Label; +import net.rptools.maptool.model.Token; +import net.rptools.maptool.model.Token.Type; + +/** + * The FlatImageLabelFactory class is responsible for creating instances of FlatImageLabel objects. + * It provides methods to customize the labels based on different parameters. + */ +public class FlatImageLabelFactory { + + /** The singleton instance of the FlatImageLabelFactory class for NPC labels */ + private final FlatImageLabel npcImageLabel; + + /** The singleton instance of the FlatImageLabelFactory class for PC labels */ + private final FlatImageLabel pcImageLabel; + + /** The singleton instance of the FlatImageLabelFactory class for non-visible token labels */ + private final FlatImageLabel nonVisibleImageLabel; + + /** Creates a new instance of the FlatImageLabelFactory class. */ + public FlatImageLabelFactory() { + var npcBackground = AppPreferences.getNPCMapLabelBG(); + var npcForeground = AppPreferences.getNPCMapLabelFG(); + var npcBorder = AppPreferences.getNPCMapLabelBorder(); + var pcBackground = AppPreferences.getPCMapLabelBG(); + var pcForeground = AppPreferences.getPCMapLabelFG(); + var pcBorder = AppPreferences.getPCMapLabelBorder(); + var nonVisBackground = AppPreferences.getNonVisMapLabelBG(); + var nonVisForeground = AppPreferences.getNonVisMapLabelFG(); + var nonVisBorder = AppPreferences.getNonVisMapLabelBorder(); + int fontSize = AppPreferences.getMapLabelFontSize(); + var font = AppStyle.labelFont.deriveFont(AppStyle.labelFont.getStyle(), fontSize); + boolean showBorder = AppPreferences.getShowMapLabelBorder(); + int borderWidth = showBorder ? AppPreferences.getMapLabelBorderWidth() : 0; + int borderArc = AppPreferences.getMapLabelBorderArc(); + + npcImageLabel = + new FlatImageLabel( + 4, + 4, + npcForeground, + npcBackground, + npcBorder, + font, + Justification.Center, + borderWidth, + borderArc); + pcImageLabel = + new FlatImageLabel( + 4, + 4, + pcForeground, + pcBackground, + pcBorder, + font, + Justification.Center, + borderWidth, + borderArc); + nonVisibleImageLabel = + new FlatImageLabel( + 4, + 4, + nonVisForeground, + nonVisBackground, + nonVisBorder, + font, + Justification.Center, + borderWidth, + borderArc); + } + + /** + * Retrieves the appropriate map image label based on the provided token. + * + * @param token The token representing the entity on the map. + * @return The map image label corresponding to the token type, and/or visibility. + */ + public FlatImageLabel getMapImageLabel(Token token) { + if (!token.isVisible()) { + return nonVisibleImageLabel; + } else if (token.getType() == Type.NPC) { + return npcImageLabel; + } else { + return pcImageLabel; + } + } + + /** + * Retrieves the map image label based on the provided label. + * + * @param label The label containing the properties for the map image label. + * @return The map image label with the specified properties. + */ + public FlatImageLabel getMapImageLabel(Label label) { + var font = AppStyle.labelFont.deriveFont(AppStyle.labelFont.getStyle(), label.getFontSize()); + var bg = label.isShowBackground() ? label.getBackgroundColor() : new Color(0, 0, 0, 0); + int borderSize = label.isShowBorder() ? label.getBorderWidth() : 0; + return new FlatImageLabel( + 4, + 4, + label.getForegroundColor(), + bg, + label.getBorderColor(), + font, + Justification.Center, + borderSize, + label.getBorderArc()); + } +} diff --git a/src/main/java/net/rptools/maptool/client/tool/texttool/EditLabelDialogView.form b/src/main/java/net/rptools/maptool/client/tool/texttool/EditLabelDialogView.form index 91025b1402..6c4b9ae292 100644 --- a/src/main/java/net/rptools/maptool/client/tool/texttool/EditLabelDialogView.form +++ b/src/main/java/net/rptools/maptool/client/tool/texttool/EditLabelDialogView.form @@ -1,9 +1,9 @@

- + - + @@ -19,7 +19,7 @@ - + @@ -27,7 +27,7 @@ - + @@ -37,7 +37,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -74,13 +74,112 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/net/rptools/maptool/client/tool/texttool/EditLabelDialogView.java b/src/main/java/net/rptools/maptool/client/tool/texttool/EditLabelDialogView.java index 490184addd..43056db8a1 100644 --- a/src/main/java/net/rptools/maptool/client/tool/texttool/EditLabelDialogView.java +++ b/src/main/java/net/rptools/maptool/client/tool/texttool/EditLabelDialogView.java @@ -16,10 +16,55 @@ import java.awt.*; import javax.swing.*; +import net.rptools.maptool.client.swing.ColorWell; +/** + * The EditLabelDialogView class represents a dialog view for editing a label. It contains + * components for specifying label properties such as border color, border width, and border arc. + * The dialog view can be accessed by calling the getRootComponent() method, which returns the root + * component of the view. + */ public class EditLabelDialogView { + /** The main panel for the dialog. */ private JPanel mainPanel; + /** Checkbox to determine whether to show the border. */ + private JCheckBox showBorderCheckBox; + + private ColorWell borderColor; + + /** Spinner for specifying the border width. */ + private JSpinner borderWidth; + + /** Spinner for specifying the border arc. */ + private JSpinner borderArc; + + /** + * The EditLabelDialogView class represents a dialog view for editing a label. It contains + * components for specifying label properties such as border color, border width, and border arc. + * The dialog view can be accessed by calling the getRootComponent() method, which returns the + * root component of the view. + */ + public EditLabelDialogView() { + showBorderCheckBox.addActionListener( + e -> { + if (showBorderCheckBox.isSelected()) { + borderColor.setVisible(true); // disabling a ColorWell does nothing. + borderWidth.setEnabled(true); + borderArc.setEnabled(true); + } else { + borderColor.setVisible(false); // disabling a ColorWell does nothing. + borderWidth.setEnabled(false); + borderArc.setEnabled(false); + } + }); + } + + /** + * Retrieves the root component of the EditLabelDialogView class. + * + * @return The root component of the EditLabelDialogView class. + */ public JComponent getRootComponent() { return mainPanel; } diff --git a/src/main/java/net/rptools/maptool/client/tool/texttool/TextTool.java b/src/main/java/net/rptools/maptool/client/tool/texttool/TextTool.java index dc591623c2..2d6eef9a51 100644 --- a/src/main/java/net/rptools/maptool/client/tool/texttool/TextTool.java +++ b/src/main/java/net/rptools/maptool/client/tool/texttool/TextTool.java @@ -24,6 +24,7 @@ import javax.swing.Action; import javax.swing.JButton; import javax.swing.JDialog; +import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; @@ -40,18 +41,31 @@ import net.rptools.maptool.model.Label; import net.rptools.maptool.model.ZonePoint; -/** */ +/** + * The TextTool class represents a tool that allows users to add and edit labels in a graphical + * editor. It extends the DefaultTool class and implements the ZoneOverlay interface. + */ public class TextTool extends DefaultTool implements ZoneOverlay { + /** The serial version UID. */ private static final long serialVersionUID = -8944323545051996907L; + /** + * Represents the currently selected Label object. + * + * @see Label + */ private Label selectedLabel; + /** The horizontal offset for dragging the element. */ private int dragOffsetX; + + /** The vertical offset of the drag operation. */ private int dragOffsetY; + + /** Is the Label being dragged. */ private boolean isDragging; - private boolean selectedNewLabel; - public TextTool() {} + private boolean selectedNewLabel; @Override protected void attachTo(ZoneRenderer renderer) { @@ -76,6 +90,12 @@ public String getInstructions() { return "tool.label.instructions"; } + /** + * Paints the overlay for the given ZoneRenderer using the provided Graphics2D object. + * + * @param renderer the ZoneRenderer object used to render the zone + * @param g the Graphics2D object used for rendering + */ public void paintOverlay(ZoneRenderer renderer, Graphics2D g) { if (selectedLabel != null && renderer.getLabelBounds(selectedLabel) != null) { AppStyle.selectedBorder.paintWithin(g, renderer.getLabelBounds(selectedLabel)); @@ -182,11 +202,24 @@ public void mouseDragged(MouseEvent e) { renderer.repaint(); } + /** + * The EditLabelDialog class is a dialog box that allows the user to edit a label. It extends the + * JDialog class and provides functionality for displaying and interacting with the label editing + * panel. + */ public class EditLabelDialog extends JDialog { + /** The serial version UID. */ private static final long serialVersionUID = 7621373725343873527L; + /** Indicates whether the changes have been accepted. */ private boolean accepted; + /** + * Constructs a new EditLabelDialog. + * + * @param label the label to be edited + * @since [version number or first version] + */ public EditLabelDialog(Label label) { super(MapTool.getFrame(), I18N.getText("tool.label.dialogtitle"), true); setDefaultCloseOperation(DISPOSE_ON_CLOSE); @@ -199,6 +232,11 @@ public EditLabelDialog(Label label) { pack(); } + /** + * Checks if the changes made in the dialog have been accepted. + * + * @return true if the changes have been accepted, false otherwise + */ public boolean isAccepted() { return accepted; } @@ -212,6 +250,11 @@ public void setVisible(boolean b) { } } + /** + * EditLabelPanel is a GUI panel used for editing label properties. It extends the AbeillePanel + * class and provides functionality for binding a Label model, committing changes to the model, + * and initializing the user interface components. + */ public class EditLabelPanel extends AbeillePanel